Himu\’s Attempt at Blogging

Tidbits from my thoughts

Active Directory Authentication using Java/JNDI

with 20 comments

I’ve successfully performed AD authentication using JNDI from Java. It is almost a copy of the code found in Mauricio Rojas Blog. Thanks Mauricio!

The ADAuthenticator class tries to connect to the AD using the given credentials and retuns a Map containing some information of the user if authentication succeeds. It can be instantiated to authenticate to a default AD or a specific AD in the constructor.

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class ADAuthenticator 
{
  private String domain;
  private String ldapHost;
  private String searchBase;
  
  public ADAuthenticator()
  {
    this.domain = "<your domain>";
    this.ldapHost = "ldap://<your AD controller>";
    this.searchBase = "your AD root e.g. dc=abbl,dc=org";
  }

  public ADAuthenticator(String domain, String host, String dn)
  {
    this.domain = domain;
    this.ldapHost = host;
    this.searchBase = dn;
  }

  public Map authenticate(String user, String pass)
  {
    String returnedAtts[] ={ "sn", "givenName", "mail" };
    String searchFilter = "(&(objectClass=user)(sAMAccountName=" + user + "))";
    
    //Create the search controls
    SearchControls searchCtls = new SearchControls();
    searchCtls.setReturningAttributes(returnedAtts);
    
    //Specify the search scope
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, ldapHost);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, user + "@" + domain);
    env.put(Context.SECURITY_CREDENTIALS, pass);
    
    LdapContext ctxGC = null;
    
    try
    {
      ctxGC = new InitialLdapContext(env, null);
      //Search objects in GC using filters
      NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
      while (answer.hasMoreElements())
      {
        SearchResult sr = (SearchResult) answer.next();
        Attributes attrs = sr.getAttributes();
        Map amap = null;
        if (attrs != null)
        {
          amap = new HashMap();
          NamingEnumeration ne = attrs.getAll();
          while (ne.hasMore())
          {
            Attribute attr = (Attribute) ne.next();
            amap.put(attr.getID(), attr.get());
          }
          ne.close();
        }
          return amap;
      }
    }
    catch (NamingException ex)
    {
      ex.printStackTrace();
    }
    
    return null;
  }
}
Advertisements

Written by mhimu

March 18, 2009 at 1:20 pm

Posted in Java

Tagged with ,

20 Responses

Subscribe to comments with RSS.

  1. FYI, this solution transmits the password in plain text in the first bindRequest call to the LDAP server.

    Ed Norris

    August 14, 2009 at 4:03 am

  2. Thanks for this write up and help.

    iqtf

    September 10, 2009 at 6:44 am

  3. would it be possible to submit the code that calls this class, and processes the returned data?

    randie

    October 29, 2009 at 10:24 pm

    • Hi randie, look at the following code:

      public class Main {
      public static void main(String[] args) {
      ADAuthenticator ada = new ADAuthenticator(“your.domain”, “ldap://adserveraddr”, “dc=your,dc=domain”);
      Map umap = ada.authenticate(“randie”, “s3cret”);
      if (umap == null)
      System.out.println(“login failed”);
      else {
      // umap has three attributes: sn, givenName, mail
      }
      }
      }

      mhimu

      November 3, 2009 at 11:25 am

  4. can you give more more information about what searchBase is supposed to be?

    randie

    October 29, 2009 at 10:59 pm

    • searchBase is the root of the active directory tree as seen by LDAP. If your domain name is xyz.com then your searchBase is ‘dc=xyz,dc=com’ (without the quotes 🙂 )

      mhimu

      November 3, 2009 at 11:27 am

      • i am doing the same but it is not working. my domain name is test.ad and i am putting searchbase=”dc=test,dc=ad”, but its not working. can you tell me what can be the problem?

        Dharmendra Bhuva

        September 6, 2011 at 4:10 pm

  5. I use this library. It s great and easy to use.
    http://code.google.com/p/jedi-obi/

    Xhumeau

    April 16, 2011 at 2:33 am

  6. Thanks for this article, it was very useful.

    Adnan

    June 28, 2011 at 3:21 pm

  7. Excellent post. You save me hours of work!

    Amber Osterman

    September 23, 2011 at 2:01 am

  8. Great thing! Thanks!

    May be useful – code to find AD server

    public static String getADServer( String domain)
    throws NamingException
    {
    Hashtable env = new Hashtable();
    env.put(“java.naming.factory.initial”, “com.sun.jndi.dns.DnsContextFactory”);
    env.put(“java.naming.provider.url”, “dns:”);
    DirContext ctx = new InitialDirContext(env);
    Attributes attrs = ctx.getAttributes(“_ldap._tcp.dc._msdcs.” + domain, new String[] { “SRV” });
    String record = (String)attrs.get(“SRV”).get();
    String[] s = record.split(” “);
    return s[s.length-1].substring(0, s[s.length-1].length()-1);
    }

    Artem

    March 12, 2012 at 2:28 pm

  9. Thanks indeed – I have this working as well. It would have taken me weeks to sort this without your post.

    russasaurous

    April 4, 2012 at 10:52 pm

    • Can you have your working code post on this thread?

      Siva

      April 20, 2012 at 2:34 am

  10. Thank you for the code, it’s very comprehensive, but, my knowledge in AD is still too poor to understand the true meanging of the following stacktrace. I do not understand the true nature of the error message. I can connect to the AD with the small tool called ADExplorer if I use the same credentials. Would it be correct to suppose, that the problem lies in the JVM settings?

    javax.naming.ServiceUnavailableException: dm.int:636; socket closed
    at com.sun.jndi.ldap.Connection.readReply(Connection.java:419)
    at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:340)
    at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:192)
    at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2694)
    at com.sun.jndi.ldap.LdapCtx.(LdapCtx.java:293)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
    login failed
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.init(InitialContext.java:223)
    at javax.naming.ldap.InitialLdapContext.(InitialLdapContext.java:134)
    at adtest.ADAuthenticator.authenticate(ADAuthenticator.java:55)
    at adtest.ADTest.main(ADTest.java:20)

    Nick Fischer

    July 26, 2012 at 7:25 pm

  11. Another important factor is budget which should be kept always in mind
    while hiring a designing firm. This interpretation is very vital for the
    attractiveness of the firm and also it reflects the persona of the brand.

    A good logo not only creates the identity but it also projects the business
    in a professional and enticing manner; thus, bringing it more and more customers.

  12. This is what I was looking for, thanks!

    SzestKam

    September 9, 2013 at 3:28 pm

  13. saved me a lot of time and works as expected… thank you!

    yves030

    January 15, 2014 at 8:34 pm

  14. +1

    John Castell

    February 12, 2014 at 12:56 am

  15. Wonderful blog! I found it while surfing around on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thanks gckeedecbgdf

    Johnk678

    May 15, 2014 at 9:48 pm

  16. Hey Guys, I tried make a test conection with this LDAP server ( http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/ ), but a recive this Eclipse console error “javax.naming.InvalidNameException: [LDAP: error code 34 – invalid DN]”. Here is my edit code ( http://pastebin.com/sQFPAz9J ). Can anyone give me a explanation, solution, light or a north? Thank’s!

    Yuri de Souza Vidal

    October 2, 2015 at 11:57 pm


Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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

%d bloggers like this: