Active Directory Authentication in Java

Doing Active Directory authentication in Java can be a nightmare. Documentation is scarse and Java APIs are usually counter-intuitive.

I’ve spent a good time to get it right (or what I guess is right), and I hope that this code sample can help others. Just use it, code is under WTFPL license.

Summary to validate if a user is in a group:

  1. Java requires the user full DN to authenticate;
  2. Authenticate to LDAP using a master user;
  3. Search user DN;
  4. Reauthenticate using user DN;
  5. Fetch all groups of user;
  6. Check if the required group is in it.
package com.tnegri.sample;

import java.util.*;

import javax.naming.*;

public final class ActiveDirectoryFacade {

    private static final MASTER_USER_DN;
    private static final MASTER_PASSWORD;

    static {
        // Sample configuration.
        MASTER_USER_DN = "CN=masteruser,OU=Users,DC=tnegri,DC=com";
        MASTER_PASSWORD = "m4sterP4ssw0rd";

    private final String ldapUrl;
    private final String searchBase;

     * @param ldapUrl LDAP URL, e.g. "ldap://"
     * @param searchBase Base for doing user search, 
     *                   e.g. "OU=Users,DC=tnegri,DC=com"
    public ActiveDirectoryFacade(String ldapUrl, String searchBase) {
        this.ldapUrl = ldapUrl;
        this.searchBase = searchBase;

    public boolean hasGroup(String username, String password, 
                            String groupObjectName) 
            throws NamingException {
        List<String> allGroups = getAllGroups(username, password);
        return allGroups.contains(groupObjectName);

    private List<String> getAllGroups(String username, String password)
            throws NamingException {
        List<String> result = new ArrayList<>();

        String attributeToLookup = "memberOf";

         * 1. Authenticate using master user.
        DirContext ctx = authenticate();

         * 2. Searches by "sAMAccountName" to recover the full
         *    DN of the username trying to login.
        SearchControls searchControls = new SearchControls();
                new String[] {"distinguishedName"});
        NamingEnumeration<SearchResult> searchResults =
                String.format("(sAMAccountName=%s)", username),
        if (!searchResults.hasMore()) {
             * If can't resolve DN, the user doesn't exists.
            throw new NamingException();
        SearchResult searchResult =;
        Attributes attributes = searchResult.getAttributes();
        Attribute attribute = attributes.get("distinguishedName");
        String userObject = (String) attribute.get();

         * 3. Authenticates to LDAP with the user, will throw if
         *    password is wrong.
        ctx = authenticate(userObject, password);

         * 4. Fetch all groups of user.
        attributes = ctx.getAttributes(userObject, 
                                       new String[] {attributeToLookup});

        NamingEnumeration<? extends Attribute> allAttributes =
        while (allAttributes.hasMoreElements()) {
            attribute = allAttributes.nextElement();
            int size = attribute.size();
            for (int i = 0; i < size; i++) {
                String attributeValue = (String) attribute.get(i);


        return result;

    private DirContext authenticate() throws NamingException {
        return authenticate(null, null);

    private DirContext authenticate(String username, String password)
            throws NamingException {
        String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
        String securityAuthentication = "simple";

        Hashtable<String, String> env = new Hashtable<>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
        env.put(Context.SECURITY_AUTHENTICATION, securityAuthentication);
        env.put(Context.PROVIDER_URL, ldapUrl);
                username != null ? username : MASTER_USER_DN);
                password != null ? password : MASTER_PASSWORD);

        DirContext ctx = new InitialDirContext(env);

        return ctx;

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s