Summary

I had written blog post simple and easy to understand about ‘Querying Active Directory using C#’ then I thought to provide similar approach/article ‘Querying Active Directory using Java’, this article is all about how to achieve in Java.

I will take you through below elements in detail-

  • How to get user details or Object from Active Directory based on Username (sAMAccountName)?
  • How to get user details or Object from Active Directory based on user Email ID?

To know more about filters, attributes/properties you can use for active directory query.


Required Details

  • LDAP address (For e.g.: myjeeva.com or IP of the Domain Controller/Global Catalog[GC])
  • Port # where would you to like search user details? Detailed Article ( For e.g.: 3289 or 38)
  • Domain Username
  • Domain Password

Useful References


How to do – Step by Step explaination

For an easy understanding perspective; I will be following line by line approach.  Active Directory Class file and example of how to use that Active Directory class file in java program. Downloads of these files you will find below.

Step 1: Compose LDAP address and supply following parameters username, password, ldap address as domain into Active Directory constructor

ActiveDirectory activeDirectory = new ActiveDirectory(username, password, domain);

Step 2:  invoke ‘searchUser’ method with search term, choice and search base

NamingEnumeration<SearchResult> result = 
		activeDirectory.searchUser(searchTerm, choice, “DC=myjeeva,DC=com”);

Step 3: Now you have your search result in ‘result‘ variable


How it works?

Part 1: ActiveDirectory constructor

  • It creates properties instance with given values (ldap address, username, password)
  • It initializes the Directory Context
  • It assign the Search Scope and return attribute names
public ActiveDirectory(String username, String password, String domainController) {
	properties = new Properties();        
	
	properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
	properties.put(Context.PROVIDER_URL, "LDAP://" + domainController);
	properties.put(Context.SECURITY_PRINCIPAL, username + "@" + domainController);
	properties.put(Context.SECURITY_CREDENTIALS, password);
	
	// initializing active directory LDAP connection
	try {
	    dirContext = new InitialDirContext(properties);
	} catch (NamingException e) {
	    LOG.severe(e.getMessage());
	}
	
	// default domain base for search
	domainBase = getDomainBase(domainController);
	
	// initializing search controls
	searchCtls = new SearchControls();
	searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	searchCtls.setReturningAttributes(returnAttributes);
}

Part 2: searchUser Method utilizes the filter method to construct the active directory query

public NamingEnumeration<SearchResult> searchUser(String searchValue, 
				String searchBy, String searchBase) throws NamingException {
	String filter = getFilter(searchValue, searchBy);
	
	// For eg.: "DC=myjeeva,DC=com";
	String base = (null == searchBase) ? domainBase : getDomainBase(searchBase); 
	
	return this.dirContext.search(base, filter, this.searchCtls);
}


private String getFilter(String searchValue, String searchBy) {
    String filter = this.baseFilter;        
    if(searchBy.equals("email")) {
        filter += "(mail=" + searchValue + "))";
    } else if(searchBy.equals("username")) {
        filter += "(samaccountname=" + searchValue + "))";
    }
    return filter;
}

Downloadable Artifacts

ActiveDirectory.java
SampleUsageActiveDirectory.java


Closure

That’s it, you have learned querying the active directory in java and you can download artifacts.  Try yourself with class provided above and experiment it.

For any queries please leave a comment!

  • http://pdtechguru.wordpress.com/2012/10/04/active-directory-health-check/ pdtechguru
    • jeevatkm

      @pdtechguru Thanks for visiting. I went through above provided link. In windows server you have shown how to pull out attribute values from Active Directory in server GUI. I hope it helps someone on this track!

  • Djouani Ramissa

    Actually I want to query AD for user certificate and I don’t know how to do that ?

    • http://myjeeva.com/ Jeevanandam M.

      @Djouani Ramissa – Not to worry, I will add the code snippet for user certificate retrieval and manipulation by tomorrow.

      Cheers,
      Jeeva

      • http://myjeeva.com/ Jeevanandam M.

        @Djouani Ramissa – Here you go, follow the article for user object retrieval. Code snippet for User Certificate access-

        Object certObj = attrs.get("userCertificate");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.flush();
        oos.close();

        InputStream certificateStream = new ByteArrayInputStream(baos.toByteArray());
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Collection certificateCollection = cf.generateCertificates(certificateStream);

        Iterator i = c.iterator()
        while(i.hasNext()) {
        Certificate cert = (Certificate)i.next();

        // use your logic here
        }

        If possible, I will write an article for Certificate Manipulation in AD.

        Cheers,
        Jeeva

  • Fabrizio Alberti

    Hi. Very useful. I see the sample, where i can find the declared package com.myjeeva.ad ???

    • http://myjeeva.com/ Jeevanandam M.

      Thanks, ActiveDirectory class defined in com.myjeeva.ad

      Once you download these java files ActiveDirectory.java, SampleUsageActiveDirectory.java (links provided above). Open up, will be able to see.

      • Fabrizio Alberti

        Sorry, but I don’t understand what you mean. I don’t need a jar file?

        • http://myjeeva.com/ Jeevanandam M.

          Hmm, actually I was trying to say is; it is single Java class utilizing JDK classes for AD interaction. So no jar file :)

          • Fabrizio Alberti

            Thanks for your reply, but so I don’t understand how to compile them from Javac command.

          • http://myjeeva.com/ Jeevanandam M.

            You can compile individually or together, as follows:

            javac ActiveDirectory.java SampleUsageActiveDirectory.java

            execute SampleUsageActiveDirectory for sample execution providing domain details OR run SampleUsageActiveDirectory.java from any Java/J2EE IDE for execution.

            Please let know, if you have any doubts.

          • Fabrizio Alberti

            After compiling all and running SampleUsageActiveDirectoy say the class was not found..

          • http://myjeeva.com/ Jeevanandam M.

            Okay, If you’re using these two classes in java project you will not face any issues, since these classes will reside in appropriate package. Will execute smoothly.

            If you would like to execute it from command line. Go-ahead and comment out below line from two java file.
            //package com.myjeeva.ad;

            Then compile it -
            javac ActiveDirectory.java SampleUsageActiveDirectory.java

            and then execute it -
            java SampleUsageActiveDirectory

            I hope this helps!

          • Fabrizio Alberti

            YES! Thanks a lot.

  • Annapoorna Shanmugam

    This is the error i get when run the file SampleUsageActiveDirectory.java
    Please help me..
    Output:

    Querying Active Directory Using Java

    ————————————

    Provide username & password for connecting AD

    Enter Domain:

    ldap://win-hltvptn9pgq.anu.com:389

    Enter username:

    annapoorna

    Enter password:

    Nopassworddc1

    Search by username or email:

    username

    Enter search term:

    annapoorna

    Feb 4, 2014 2:05:05 PM ActiveDirectory

    SEVERE: Invalid name: /win-hltvptn9pgq.anu.com:389

    Exception in thread “main” java.lang.NullPointerException

    at ActiveDirectory.searchUser(ActiveDirectory.java:67)

    at SampleUsageActiveDirectory.main(SampleUsageActiveDirectory.java:149)

  • padilla

    why me!!!?? plese help

    SEVERE: [LDAP: error code 49 – 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1772
    Exception in thread “main” java.lang.NullPointerException
    at ActiveDirectory.searchUser(ActiveDirectory.java:120)
    at Main.main(Main.java:43)

    • http://myjeeva.com/ Jeevanandam M.

      @disqus_xp0UEXAhRX:disqus it seems, incorrect DN use against LDAP.

      DN means: “CN=Users,DC=domain,DC=com”

      Error code 49 means ‘bad credentials at login’

      I hope it helps, to figure out your problem.

      Cheers,
      Jeeva

    • http://myjeeva.com/ Jeevanandam M.

      @disqus_xp0UEXAhRX:disqus In addition to previous reply, for your reference http://ldapwiki.willeke.com/wiki/Common%20Active%20Directory%20Bind%20Errors

      Cheers,
      Jeeva

      • padilla

        ok… I had put an IP instead of the domain: eg: mydomain.co.cu…. already fix that… but now he tells me: “SEVERE: mydomain.co.cu:389″… how I can do that in IP version? …mydomain is not in internet… it is a local net

  • padilla

    why??
    // the next line code gift me this error (java.lang.NullPointerException)

    return this.dirContext.search(base, filter, this.searchCtls);
    —————————————
    can you give me an example that only test the connection? because maybe an error occurred by my Active Directory hierarchy

    maybe my “baseFilter” have a error

    or maybe I need specify “OU=Subfolder_2,OU=Subfolder_1,DC=mydomain,DC=co,DC=cu”

    can you help me please?

    • http://myjeeva.com/ Jeevanandam M.

      @disqus_xp0UEXAhRX:disqus use http://www.ldapadmin.org/download/ldapadmin.html for verifying LDAP information you have (ldap url, userdn, base, port no, query, etc…) and then use it in the Java program.

      Cheers,
      Jeeva

      • padilla

        my friend… you can sleep well this night… you helped me a lot…. but … I changed some code

        properties.put(Context.PROVIDER_URL, “LDAP://192.168.1.3:389″);
        ——————–
        String base = (null == searchBase) ? “OU=myOrg,”+domainBase : getDomainBase(searchBase);

        thank you, I’m very happy now..

  • Velius R.A.
    • http://myjeeva.com/ Jeevanandam M.

      @veliusra:disqus I have pushed ‘pom.xml’ to generic-repo in github.

      1. Take a git clone of https://github.com/jeevatkm/generic-repo
      2. Go to directory ‘ActiveDirectoryJava’
      3. Execute ‘mvn eclipse:clean eclipse:eclipse’

      4. Eclipse IDE project configuration is ready; import a project into eclipse

      Cheers,
      Jeeva

      • Velius R.A.

        Thanks so much, you’re so faster.

  • padilla

    hi again Jeeva!…. now …I have another problem… I need the list of users that exist in a given OU

    eg:.
    public Arraylist getMyUsers (String OU_name){
    Arraylist list =???????????;
    return list;
    }

    thank again…. padilla

    • http://myjeeva.com/ Jeevanandam M.

      padilla for that you have a domain base like “OU=Sales,DC=example,DC=Com” an then base filter like this “(&((&(objectCategory=Person)(objectClass=User)(objectClass=organizationalUnit)))”.

      Then fire it, you will get all users belongs to OU. Be careful with result set, it could be huge so handle it wisely.

      Good luck!

      Cheers,
      Jeeva

      • padilla

        ok, mmm…
        I add the OU en the domain base!!… ok no problem!
        the base filter… ok no problem!

        but, I need modify the filter because I don’t search by username or email…I need ALL users of this OU… so ..

        String filter =”OU=myOU”;

        but… this return me the OU information , but How I can get the sAMAccountName user list???

      • padilla

        ok…don’t worry… I find the way. thank …

        • http://myjeeva.com/ Jeevanandam M.

          Thanks!

  • Mohan

    Hi I want to add wild cards to query the active directory based on firstname and forename how could this be done?

  • padilla

    Hi again, now i have other problem, i need change any password account in the AD, but java say that need SSL conection becouse change pass is dangerous… ok..

    so, I change to port 636

    properties.put(Context.SECURITY_PROTOCOL, “ssl”);

    but now i need a certificate … so.. how a can get or import the certification automaticaly in the same code and acept it ?

    or how i can ignore the certificate?
    or how i can get the certificate file from the certificate server and manually add to the JVM

  • Jayesh Baviskar

    Hello Jeevanandam,

    This is what I am looking for from several weeks. I want to access AD user data inside my java code.

    I am trying your sample code snippets but i am facing following error. Please guide / help me as early as possible to get rid off this error.

    I am giving input details as follows,

    domain=”adserver.mycompany.com”;
    username=”jayesh”;
    password=”[email protected]”;
    choice=”email”;
    searchTerm=”CN=Jayesh Baviskar,OU=TEAM,OU=PUNE,DC=adserver,DC=mycompany,DC=com”;

    Exception in thread “main” javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name ‘DC=ADSERVER,DC=MYCOMPANY,DC=COM’
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
    at com.sun.jndi.ldap.LdapCtx.searchAux(Unknown Source)
    at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source)
    at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(Unknown Source)
    at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source)
    at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source)
    at javax.naming.directory.InitialDirContext.search(Unknown Source)
    at com.mycompany.ada.ActiveDirectoryAccess.searchUser(ActiveDirectoryAccess.java:82)
    at com.mycompany.ada.SampleUsageActiveDirectoryApp.main(SampleUsageActiveDirectoryApp.java:46)

    Thanks in advance.

    Jayesh

    • Vaibhav Bayeet

      Hello Jeevanandam,

      I am also facing the same issue as Jayesh. Can u please reply for this.

      Thanks and Regards,
      Vaibhav

  • Krishna Rajesh

    hi jeeva, I have tried with your example.. but couldnt get o/p..

    Is searchbase,search filter are necessary while querying from LDAP using java code.

    I need department number of a particular user after got access to ldap server. Please help me in it