Sunday, January 28, 2007

Java: Intro to LDAP

I am just coming off of an assignment where part of the task was to implement an authentication routine against a LDAP repository. Having never worked with LDAP before, I downloaded IBM’s Tivoli Directory Server and followed the instructions here to getting it set up and getting a basic directory. The version I used was 5.1. While doing the install, I did end up having a problem with DB2 when I got to the point of configuring the database for LDAP. To correct this I had to re-install DB2 from the installation disk seperatly and install a fix level (sorry for the lack of instructions on that, I’m writing this after the fact, so I don’t have the specifics).

Anyway, below is my resulting test program. While different LDAP repositories can follow different schemas (such as the one I had to work with in real time used different attribute names), this one will work for the one in the IBM tutorial listed above. Working with LDAP can be tricky if you’ve never worked with it before due to the confusion of using full DN’s vs when you can use RDN’s. Basically, LDAP is just a repository for named user objects. In the IBM example, you have a user, with particular attributes, and each user is stored in the people tree of the repository. What gets confusing is the use of DN’s. DN’s are the names. To access things, you reference a full DN to search for one that has a particular attribute that matches. You can pretty much always use DN’s anywhere, and writing a small utility method that will append the full DN to a RDN can be helpful.

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
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;

import java.util.Hashtable;
import java.util.ArrayList;

public class javaLdapTEst {

public static void main(String[] args) {
Hashtable contextSetup = new Hashtable(); //contains the configuration for the context setup
String uidToSearch = "(uid=c0001)"; //The user ID we are searching for
String baseDN = "dc=ibm, dc=com"; //The base DN for the entire LDAP structure
String baseUserDN = "ou=people, " + baseDN; //the base DN to use to search for people. This will
//contain the full DN for the users tree. Role trees
//are usually contained in a seperate node, which is
//outside of the scope of this example

//create the parameters to use during initialization of the LDAP context
contextSetup.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
contextSetup.put(Context.PROVIDER_URL, "ldap://192.168.254.128:389");
contextSetup.put(Context.SECURITY_CREDENTIALS, "ibm4root");
contextSetup.put(Context.SECURITY_PRINCIPAL , "cn=root,");
contextSetup.put(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");

try {
//Create the context used to communicate with the LDAP server throughout
DirContext dContext = new InitialDirContext(contextSetup);

//SEtup the search object. With this, we will pass in a base DN, and search all the child nodes
//In the ldap
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

//Execute the search, and display all the resulting attributes, and display all matches
for (NamingEnumeration results = dContext.search(baseUserDN, uidToSearch, searchControls); results.hasMore();)
{
//Get the next individual result
SearchResult result = (SearchResult)results.next();

//Print out the name
System.out.println(result.getName());

//Display all resulting attributes
for (NamingEnumeration attributes = result.getAttributes().getAll(); attributes.hasMore();)
{
String attribute = attributes.next().toString();
System.out.println(attribute);
}

//Display the email addresses that this user has
for (NamingEnumeration mail = result.getAttributes().get("mail").getAll(); mail.hasMore();)
{
System.out.println("Email addresses: " + mail.next().toString());
}

System.out.println("---------------------------------\n\n");

}
} catch (NamingException e) {
e.printStackTrace();
}
}

}

No comments: