开发者

LDAP user password authentication using JNDI

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,o开发者_开发问答u=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

javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]

I am authenticated when is specified as cn=John but not uid=103. Am I not allowed to specify by uid?


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):

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 uid instead. 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=QuizPortal in your example).


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.


It looks like a server configuration issue. Here's a similar problem including a solution. Basically you'll have to specify whether to use uid or cn for authentication in ldap-authentication.properties.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜