LDAP 认证方式

在 LDAP 中,通过“绑定”操作提供身份验证信息。在 LDAP v2 中,Client 端通过向服务器发送包含身份验证信息的“绑定”操作来启动与 LDAP 服务器的连接。

在 LDAP v3 中,此操作具有相同的 Object,但它是可选的。发送 LDAP 请求而未执行“绑定”的 Client 端被视为匿名Client 端(有关详细信息,请参见Anonymous部分)。在 LDAP v3 中,“绑定”操作可以在连接期间的任何时间发送,可能不止一次。Client 端可以在 Connecting 间发送“绑定”请求以更改其身份。如果请求成功,则将丢弃在连接上使用旧标识的所有未完成请求,并将连接与新标识关联。

“绑定”操作中提供的身份验证信息取决于 Client 端选择的“身份验证机制”。有关身份验证机制的讨论,请参见Authentication Mechanisms

使用 JNDI 向 LDAP 进行身份验证

在 JNDI 中,认证信息在环境属性中指定。使用InitialDirContext类(或其超类或子类)创建初始上下文时,将提供一组环境属性,其中一些可能包含身份验证信息。您可以使用以下环境属性来指定认证信息。

  • Context.SECURITY_AUTHENTICATION("java\.naming\.security\.authentication")。
    指定要使用的身份验证机制。对于 JDK 中的 LDAP 服务提供者,这可以是以下字符串 之一:"none""simple",* sasl_mech ,其中 sasl_mech *是用空格分隔的 SASL 机制名称列表。有关这些字符串 的说明,请参见Authentication Mechanisms

  • Context.SECURITY_PRINCIPAL("java\.naming\.security\.principal")。
    指定执行身份验证的用户/程序的名称,并取决于Context\.SECURITY_AUTHENTICATION属性的值。有关详细信息和示例,请参见本类的下几个部分。

  • Context.SECURITY_CREDENTIALS("java\.naming\.security\.credentials")。
    指定执行身份验证的用户/程序的凭据,并取决于Context\.SECURITY_AUTHENTICATION属性的值。有关详细信息和示例,请参见本类的下几个部分。

创建初始上下文后,底层 LDAP 服务提供者从这些环境属性中提取身份验证信息,并使用 LDAP“绑定”操作将它们传递给服务器。

following example显示了 Client 端如何使用简单的明文密码向 LDAP 服务器进行身份验证。

// Set up the environment for creating the initial context
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");

// Authenticate as S. User and password "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");

// Create the initial context
DirContext ctx = new InitialDirContext(env);

// ... do something useful with ctx

为上下文使用不同的身份验证信息

如果要对现有上下文使用不同的身份验证信息,则可以使用Context.addToEnvironment()Context.removeFromEnvironment()来更新包含身份验证信息的环境属性。上下文中方法的后续调用将使用新的身份验证信息与服务器进行通信。

following example显示创建上下文后如何将上下文的身份验证信息更改为"none"

// Authenticate as S. User and the password "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");

// Create the initial context
DirContext ctx = new InitialDirContext(env);

// ... do something useful with ctx

// Change to using no authentication
ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "none");

// ... do something useful with ctx

Authentication Failures

身份验证可能由于多种原因而失败。例如,如果您提供了不正确的身份验证信息,例如不正确的密码或主体名称,则会引发AuthenticationException

这是an example,是上一个示例的变体。这次,密码错误会导致身份验证失败。

// Authenticate as S. User and give an incorrect password
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 - Invalid Credentials]
        ...

由于不同的服务器支持不同的身份验证机制,因此您可能会请求服务器不支持的身份验证机制。在这种情况下,将抛出AuthenticationNotSupportedException

这是an example,是上一个示例的变体。这次,不支持的身份验证机制("custom")导致身份验证失败。

// Authenticate as S. User and the password "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
        ...