我已经编写了一个测试代码,用于通过Active Directory服务器验证用户身份。我可以使用下面的代码使用bind dn进行身份验证。
public static void main(String[] args) {
LdapContext ldapContext = null;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://10.121.85.24:636");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_PRINCIPAL, "EXTLDAPTEST\batty"); // line 1
env.put(Context.SECURITY_CREDENTIALS, "mypassword");
env.put("com.sun.jndi.ldap.read.timeout", Integer.toString(8000));
env.put("java.naming.ldap.factory.socket", "com.auth.server.TrustAllSSLSocketFactory" );
try {
ldapContext = new InitialLdapContext(env, null);
} catch (Exception e) {
e.printStackTrace();
}
if (ldapContext != null)
{
System.out.println("Authenticatied");
}
}
但是当我用
替换第1行时env.put(Context.SECURITY_PRINCIPAL, "CN=batty,OU=Unsorted,OU=EDN Users,OU=User accounts,DC=extLDAPTest,DC=local"); // line 1
它会抛出异常
javax.naming.AuthenticationException:[LDAP:错误代码49 - 80090308:LdapErr:DSID-0C0903A9,注释:AcceptSecurityContext错误,数据52e,v1db1
AD的树形结构是:
尝试使用完整的dn进行身份验证时,我做错了吗?
编辑1 : 当我使用服务帐户使用
获取完整的dn时NamingEnumeration<?> aa = context.list("OU=Unsorted,OU=EDN Users,OU=User accounts,DC=extLDAPTest,DC=local");
我得到以下结果:
CN = batty,OU =未排序,OU = EDN用户,OU =用户帐户,DC = extLDAPTest,DC =本地
与我通过身份验证相同。
编辑2 :我使用完整dn的原因是,我将获得服务帐户和子树的dn。现在,同一个用户可以存在于不同的子树中。所以我想从特定的子树中验证它。
答案 0 :(得分:0)
与LDAP相关的错误代码49是由无效的凭据引起的。
但您可以使用ADSI Edit或AD Explorer等应用程序来获取对象的DN。您可以只使用它们来查看相关对象的“distinguishedName”属性,或者使用特定于每个应用程序的其他方法。
或用户LDAPExplorerTool 2.找出你想获得的CN的CN。你可以在secDN属性中获取它的值:
答案 1 :(得分:0)
我想知道你为什么需要使用完整的DN来指定用户名? 您可以使用 DOMAIN \ USER 或 USER @ DOMAIN 格式对AD进行身份验证。
我个人从未使用过任何其他格式,但RFC 2829指定了以下基于DN的身份验证标识格式: dn:DN 。在您的情况下,SECURITY.PRINCIPAL将看起来 dn:CN = batty,OU =未排序,OU = EDN用户,OU =用户帐户,DC = extLDAPTest,DC =本地。再一次,我从未使用DN格式,但尝试一下,看看提议的解决方案是否有效。
希望这有帮助。