Search code examples
javaauthenticationldapjndi

How to authenticate a user against AD in Java


I'm using JNDI library to access to an AD from Java Webapp. I authenticate agaisnt the AD via LDAP using a technical user as follows:

    Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
    ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT);
    ldapEnv.put(Context.PROVIDER_URL, providerUrl);
    ldapEnv.put(Context.SECURITY_AUTHENTICATION,
            SECURITY_AUTHENTICATION_SIMPLE);
    ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
    ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials);
    return new InitialDirContext(ldapEnv);

I use this user to read and write from/to AD.

But after that, I don't know how to authenticate the final user who is really accessing to my webapp with his user and a password.

I read about using find method from Context class but I'm not sure how to do or how to build the the search filter. For example

(&(cn= ....

I don't know either how to find for all users in the AD. I would like to show in my webapp a list of all available users in AD


Solution

  • -To Authenticate a user

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "LDAP://url/");
    
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "domain\\user_name");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    
    InitialLdapContext ctx = new InitialLdapContext(env,null);
    boolean authenticated = (ctx != null) ? true : false;
    

    -To Get all users' names

    public ArrayList<String> getAllUsers(LdapContext ctx) {
        ArrayList<String> users = new ArrayList<>();
        try {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
            String[] attrIDs = {"cn"};
            constraints.setReturningAttributes(attrIDs);
    
            NamingEnumeration answer = ctx.search("dc=example,dc=com", "(&(cn=*))", constraints);
    
            while (answer.hasMore()) {
                Attributes attrs = ((SearchResult) answer.next()).getAttributes();
                users.add(attrs.get("cn").toString().replace("cn:", ""));
            }
    
        } catch (Exception ex) {
        }
        return users;
    }
    

    -To Search a particular use

    public String getUserName(String username, LdapContext ctx) {
        try {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
            String[] attrIDs = {"cn"};
            constraints.setReturningAttributes(attrIDs);
    
            NamingEnumeration answer = ctx.search("OU=Employees,OU=Users,DC=sub_domain,DC=domain,DC=com", "uid=" + username, constraints);
    
            if (answer.hasMore()) {
                Attributes attrs = ((SearchResult) answer.next()).getAttributes();
                return attrs.get("cn").toString().replace("cn:", "");
            } else {
                return null;
            }
    
        } catch (Exception ex) {
        }
        return null;
    }
    

    You can get more details about search query from this