Translate

Wednesday, May 2, 2012

JNDI - Read Active Directory User Information

Today I needed to read in some user information from Active Directory so that I could create entries for each user and the uers group meberships in a SQL table.

Here is the code I used for testing:

package org.inewsnet.ldap;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.ResourceBundle;
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.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapJndi{
    @SuppressWarnings("rawtypes")
    Hashtable env;
    DirContext ctx;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public boolean  connect(){
        boolean bRes = true;
        ResourceBundle rsBun = ResourceBundle.getBundle("LDAP");
        env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://" + rsBun.getString("server") + ":" + 
           rsBun.getString("port") + rsBun.getString("root"));
        env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
        env.put(Context.SECURITY_PRINCIPAL, "cn=" + rsBun.getString("principal")); 
        env.put(Context.SECURITY_CREDENTIALS, rsBun.getString("credentials")); 
        try {
            ctx = new InitialDirContext(env);
        } catch (NamingException e) {
            e.printStackTrace();
            bRes = false;
        }
        return bRes;
    }

    public static String getCN(String cnName) {
        if (cnName != null && cnName.toUpperCase().startsWith("CN=")) {
            cnName = cnName.substring(3);
        }
        int position = cnName.indexOf(',');
        if (position == -1) {
            return cnName;
        } else {
            return cnName.substring(0, position);
        }
    }

    public static String getUserName(String upn) {
        int position = upn.indexOf('@');
        return upn.substring(0, position);
    }

    @SuppressWarnings("rawtypes")
    public boolean testNetworkRead() {
        boolean bRes = false;
        String firstName;
        String lastName;
        String userName;
        ResourceBundle rsBun = ResourceBundle.getBundle("LDAP");
        String bsaeOU = "ou=" + rsBun.getString("baseOU");
        SearchControls sc = new SearchControls();
        String[] attributeFilter = {"memberOf", "userPrincipalName", "sn", "givenName",  "cn", "mail" };
        sc.setReturningAttributes(attributeFilter);
        sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String filter = "(&(sn=*)(l=*))";

        try {
            NamingEnumeration results = ctx.search(bsaeOU, filter, sc);
            Integer iCx = 0;
            while (results.hasMore()) {
                SearchResult sr = (SearchResult) results.next();
                Attributes attrs = sr.getAttributes();
                iCx = iCx + 1;
                System.out.print(iCx + ")");
                Attribute attr = attrs.get("sn");
                lastName = attr.get().toString();
                System.out.print("ln= " + lastName);
                attr = attrs.get("givenName");
                if (attr != null) {
                    firstName = attr.get().toString();
                    System.out.print(" fn= " + firstName);
                }
                System.out.print("-");
                Attribute aupn = attrs.get("userPrincipalName");    
                userName = getUserName(aupn.get().toString());
                Attribute mattr = attrs.get("memberOf");
                System.out.println(" un= " + userName + ": ");        
                if(mattr != null) {
                    //loop through the memberof attribute to get each group
                    for ( Enumeration e1 = mattr.getAll() ; e1.hasMoreElements() ; ) {
                        System.out.println(getCN(e1.nextElement().toString()));
                    }
                }
            }//end while
            bRes = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }            
        return bRes;
    }
}

All you need to do is provide your own connection settings in the connect method. I'm getting mine from a properties file.

This is my test method calling the methods in the class above:

public String testLdapNetworkRead() throws Exception {
    LdapJndi myCon = new LdapJndi();
    try {
        if(myCon.connect()) myCon.testNetworkRead();
    } catch (Exception e) {
        this.errorMsg = e.getMessage();
        return ERROR;
    }
    successMsg = "Test Connect OK";
    return SUCCESS;
}   

No comments:

Post a Comment

Thank you for commenting!