Java,LDAP:不要忽略空白密码吗?

我正在维护一些遗留的Java LDAP代码。 我对LDAP几乎一无所知。

下面的程序基本上只是将用户标识和密码发送到LDAP服务器,如果凭据是好的,则接收通知。 如果是,则打印出从LDAP服务器接收的LDAP属性,否则会打印出exception。

如果给出错误的密码,一切都很好。 抛出“无效凭证”exception。 但是,如果将空密码发送到LDAP服务器,仍将进行身份validation,仍将返回LDAP属性。

由于LDAP服务器允许空白密码,这是不愉快的情况,还是需要调整下面的代码,这样一个空密码将以这种方式送到LDAP服务器,以免被拒绝?

我确实有数据validation。 我在测试环境中将其关闭以解决另一个问题并注意到这个问题。 我不希望在数据validation下面出现这个问题。

非常感谢您提供任何信息

import javax.naming.*; import javax.naming.directory.*; import java.util.*; import java.sql.*; public class LDAPTEST { public static void main(String args[]) { String lcf = "com.sun.jndi.ldap.LdapCtxFactory"; String ldapurl = "ldaps://ldap-cit.smew.acme.com:636/o=acme.com"; String loginid = "George.Jetson"; String password = ""; DirContext ctx = null; Hashtable env = new Hashtable(); Attributes attr = null; Attributes resultsAttrs = null; SearchResult result = null; NamingEnumeration results = null; int iResults = 0; int iAttributes = 0; env.put(Context.INITIAL_CONTEXT_FACTORY, lcf); env.put(Context.PROVIDER_URL, ldapurl); env.put(Context.SECURITY_PROTOCOL, "ssl"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com"); env.put(Context.SECURITY_CREDENTIALS, password); try { ctx = new InitialDirContext(env); attr = new BasicAttributes(true); attr.put(new BasicAttribute("uid",loginid)); results = ctx.search("ou=People",attr); while (results.hasMore()) { result = (SearchResult)results.next(); resultsAttrs = result.getAttributes(); for (NamingEnumeration enumAttributes = resultsAttrs.getAll(); enumAttributes.hasMore();) { Attribute a = (Attribute)enumAttributes.next(); System.out.println("attribute: " + a.getID() + " : " + a.get().toString()); iAttributes++; }// end for loop iResults++; }// end while loop System.out.println("Records == " + iResults + " Attributes: " + iAttributes); }// end try catch (Exception e) { e.printStackTrace(); } }// end function main() }// end class LDAPTEST 

不幸的是,使用DN和空密码进行身份validation是LDAP的难点之一,并导致服务器的“未经身份validation的”肯定响应。 某些LDAP服务器具有配置选项,用于禁用最新版本的LDAPv3(RFC 4511)中不鼓励的行为,甚至默认情况下禁用该行为。

最终,客户端应用程序应检查输入参数并确保密码不为空。

亲切的问候,

朱利

您需要从简单更改身份validation方法(这不是在生产环境中使用的方法,至少在没有SSL的情况下)。

如下所述: http : //docs.oracle.com/javase/jndi/tutorial/ldap/security/simple.html

如果提供空字符串,空字节/ char数组,或者为Context.SECURITY_CREDENTIALS环境属性提供null,则身份validation机制将为“none”。 这是因为LDAP要求密码对于简单身份validation是非空的。 如果未提供密码,协议会自动将身份validation转换为“无”。

有两种类型的BIND操作, simpleSASL 。 在简单的BIND的情况下,有四种可能性:

  • 空DN和空密码: anonymous ,不进行身份validation。 这是初始状态,也是服务器收到BIND请求时的状态
  • 非空DN,空密码: unauthenticated身份unauthenticated ,不进行身份validation
  • 非空DN,非空密码:正常情况下,尝试进行身份validation
  • 空DN,非空密码:LDAP标准中未定义服务器行为。 不进行身份validation。

最初建立连接时,连接是anonymous 。 每个BIND请求都将连接状态重置为anonymous 。 每个成功的BIND请求都会将连接的授权状态更改为可分辨名称的授权状态。 每个不成功的BIND请求都会使连接未经身份validation。

BIND的语义在LDAP:Authentication中定义

发送“空”密码时发生的情况是身份validation(即绑定)以匿名方式完成。

您的代码可以修改为检测空密码或用户ID以停止此活动。

某些LDAP实现可以阻止任何匿名绑定。