本 Java 教程是针对 JDK 8 编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用已不再可用的技术。
有关 Java SE 9 和后续版本中更新的语言功能的摘要,请参阅Java 语言变更。
有关所有 JDK 发行版的新功能、增强功能以及已移除或弃用选项的信息,请参阅JDK 发行说明。
在LDAP中,认证信息是在"bind"操作中提供的。在LDAP v2中,客户端通过发送包含认证信息的"bind"操作与LDAP服务器建立连接。
在LDAP v3中,该操作具有相同的目的,但是它是可选的。发送LDAP请求而不进行"bind"的客户端被视为匿名客户端(有关详细信息,请参见匿名部分)。在LDAP v3中,"bind"操作可以在连接期间的任何时间发送,可能会发送多次。客户端可以在连接的中间发送"bind"请求以更改其身份。如果请求成功,则丢弃使用旧身份的所有未完成请求,并将连接与新身份关联。
在"bind"操作中提供的认证信息取决于客户端选择的认证机制。有关认证机制的讨论,请参见认证机制。
在JNDI中,认证信息在环境属性中指定。当使用InitialDirContext类(或其超类或子类)创建初始上下文时,您提供一组环境属性,其中一些可能包含认证信息。您可以使用以下环境属性来指定认证信息。
当创建初始上下文时,底层LDAP服务提供程序从这些环境属性中提取认证信息,并使用LDAP的"bind"操作将它们传递给服务器。
以下示例显示了如何使用简单的明文密码,客户端对LDAP服务器进行身份验证。
// 设置创建初始上下文的环境 Hashtable<String, Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial"); // 作为S. User进行身份验证,密码为"mysecret" env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial"); env.put(Context.SECURITY_CREDENTIALS, "mysecret"); // 创建初始上下文 DirContext ctx = new InitialDirContext(env); // ... 使用ctx进行有用的操作
如果要为现有上下文使用不同的认证信息,则可以使用Context.addToEnvironment()和Context.removeFromEnvironment()来更新包含认证信息的环境属性。对上下文的后续方法调用将使用新的认证信息与服务器进行通信。
以下示例显示了在创建上下文后将上下文的认证信息更改为"none"的过程。
// 作为S. User进行身份验证,密码为"mysecret" env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial"); env.put(Context.SECURITY_CREDENTIALS, "mysecret"); // 创建初始上下文 DirContext ctx = new InitialDirContext(env); // ... 使用ctx进行有用的操作 // 更改为不使用身份验证 ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "none"); // ... 使用ctx进行有用的操作
认证可能因为多种原因而失败。例如,如果提供了不正确的认证信息,例如不正确的密码或主体名称,则会抛出AuthenticationException异常。
这里是一个例子,是前一个例子的变化。这次,错误的密码导致认证失败。
// 以S. User身份进行认证,但给出了错误的密码 env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial"); env.put(Context.SECURITY_CREDENTIALS, "notmysecret");
这将产生以下输出。
javax.naming.AuthenticationException: [LDAP: error code 49 - 无效的凭据] ...
由于不同的服务器支持不同的认证机制,您可能会请求服务器不支持的认证机制。在这种情况下,将会抛出一个AuthenticationNotSupportedException。
这里是一个例子,是前一个例子的变化。这次,不支持的认证机制("custom")导致认证失败。
// 以S. User身份进行认证,密码为"mysecret" env.put(Context.SECURITY_AUTHENTICATION, "custom"); env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial"); env.put(Context.SECURITY_CREDENTIALS, "mysecret");
这将产生以下输出。
javax.naming.AuthenticationNotSupportedException: custom ...