java 使用 JNDI 的 LDAP 用户密码认证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3456870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LDAP user password authentication using JNDI
提问by Nivek
public static void main(String[] args)
{
String INITCTX = "com.sun.jndi.ldap.LdapCtxFactory";
String MY_HOST = "ldap://Localhost:1389";
String MGR_DN = "cn=John,ou=Users,o=IT,dc=QuizPortal";
String MGR_PW = "password";
//Identify service provider to use
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, INITCTX);
env.put(Context.PROVIDER_URL, MY_HOST);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, MGR_DN);
env.put(Context.SECURITY_CREDENTIALS, MGR_PW);
try
{
// Create the initial directory context
InitialDirContext initialContext = new InitialDirContext(env);
System.out.println("Context Sucessfully Initialized");
}
catch(Exception e)
{
System.err.println(e);
}
}
I would like to ask when I set the MGR_DN = "cn=John,ou=Users,o=IT,dc=QuizPortal"to MGR_DN = "uid=103,ou=Users,o=IT,dc=QuizPortal". Basically changing from cn to uid, I would encounter an error
我想问一下,当我设置MGR_DN = "cn=John,ou=Users,o=IT,dc=QuizPortal"到MGR_DN = "uid=103,ou=Users,o=IT,dc=QuizPortal"。基本上从cn改成uid,就会报错
javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]
I am authenticated when is specified as cn=Johnbut not uid=103. Am I not allowed to specify by uid?
当指定为cn=John但不是时,我已通过身份验证uid=103。我不允许通过 uid 指定吗?
采纳答案by user207421
You have to specify the DN or distinguished name. That's the name the user is bound as in the directory. You can't just select any chain of attributes. If your users are bound via the 'cn' attribute then only the 'cn' attribute is part of the DN.
您必须指定 DN 或专有名称。这是用户在目录中绑定的名称。您不能只选择任何属性链。如果您的用户是通过“cn”属性绑定的,那么只有“cn”属性是 DN 的一部分。
回答by Bruno
If you don't know the exact DN in advance, you should do a search in the LDAP directory first. This can be done more or less like this (make sure you catch the relevant exceptions):
如果您事先不知道确切的 DN,您应该先在 LDAP 目录中进行搜索。这可以或多或少地像这样完成(确保你捕捉到相关的异常):
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapServerUrl);
env.put(Context.SECURITY_AUTHENTICATION, "none");
SearchControls searchCtrls = new SearchControls();
searchCtrls.setReturningAttributes(new String[] {});
searchCtrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(cn=" + identifier + "))";
DirContext ctx = null;
ctx = new InitialDirContext(env);
NamingEnumeration<SearchResult> answer = ctx.search(
ldapBaseDN, filter, searchCtrls);
String fullDN = null;
if (answer.hasMore()) {
fullDN = answer.next().getNameInNamespace();
ctx.close();
ctx = null;
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, fullDN);
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialDirContext(env);
return true;
}
// Exception otherwise ...
Here, the search filter is "(&(cn=" + identifier + "))"(so, for example (&(cn=John))), but you could use the uidinstead. Uniqueness of the results depends on the configuration of the LDAP server. The base DN also depends on the way it's set up (it could be ou=Users,o=IT,dc=QuizPortalin your example).
在这里,搜索过滤器是"(&(cn=" + identifier + "))"(所以,例如(&(cn=John))),但您可以使用uid代替。结果的唯一性取决于 LDAP 服务器的配置。基本 DN 还取决于它的设置方式(它可能ou=Users,o=IT,dc=QuizPortal在您的示例中)。
回答by Andreas Dolk
It looks like a server configuration issue. Here's a similar problem including a solution. Basically you'll have to specify whether to use uidor cnfor authentication in ldap-authentication.properties.
看起来像是服务器配置问题。这是一个类似的问题,包括一个解决方案。基本上,你必须指定是否使用uid或cn用于验证身份ldap-authentication.properties。

