Been learning a lot at my new job at St. Mary’s University. The university has been able to serve the students, faculty and staff via the “Gateway.” The Gateway is a portal site using a Luminis system from SunGuard. SunGuard based their system on uPortal. One of the central servers is a LDAP server. It contains course information, user information, department information, information about the current term and permission groups. With this much importance on one server I thought it would be a good idea to learn about it and how Java could interact with it.
First some background into LDAP. LDAP stands for Lightwieght DirectoryAccess Protocol. LDAP servers are a type of Directory Server witch hold collections of information(well like a directory). Good examples are phone directories. The difference between a phone directory and a directory server is that a directory server can hold a directory of any data rather than contact information. They are not replacements for relational databases. Directory servers are not designed to handle generalized data relationships like relational databases. One needs to think more one-to-one or one-to-many data sets for LDAP servers. Another difference is the speed of reading vs. writing. Most directory servers are very fast on reading data but slow on writing. Each LDAP entry has a distinguished name or dn. This is the key of the entry. It is normally composed of multiple parts of attributes found in the entry. The other part of an entry is attributes. Attributes have a name and a value. For example, an entry with a dn of “uid=mborn, ou=Users, dc=example, dc=com” has an attribute named common name or cn that has the value “Max Born.” There can be multiple values for each attribute. In the last example, there are multiple objectClass attributes, each one with a unique value. ObjectClasses are important for LDAP entries because they define what attributes an entry can contain or have to contain. ObjectClasses are defined in schemas. Normally, these files are separate from the normal configuration files. Many of the schemas used in LDAP servers are standardized so as long as the LDAP server supports a schema. The schemas that the examples use are InetOrgPerson and Java.
To run the examples, I suggest downloading and installing both sub projects from The Apache Directory Project. The Apache Directory Studio alone makes the effort worth it. The studio is LDAPv3 compliant so any LDAPv3 server can be used. I started using it on OpenLDAP because I bought “Mastering OpenLDAP” researching this subject. I switched over to Apache’s Directory because of how easy it was to use with the studio in a Microsoft Windows environment. I used the example.ldif file contained the directory server’s configuration directory. The only modification to the file was removing the users that used references. I also added an organzational unit named java to save the java objects into. I also suggest downloading and installing a JDKv1.3 or later. Java 1.3 and newer already contain the JNDI libraries that will be used throughout. I developed these examples using Java 1.6.
Here is the first example, all this does is connect to a server anonymously and find the user associated with a uid of mborn.
import javax.naming.Context;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import javax.naming.NamingException;
import java.util.Hashtable;
public class JndiClient {
static Hashtable getEnv() {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.jndi.ldap.LdapCtxFactory”);
env.put(Context.PROVIDER_URL, “ldap://localhost:10389/dc=example,dc=com”);
return env;
}
/**
* @param args
*/
public static void main(String[] args) {
try {
DirContext ctx = new InitialDirContext(getEnv());
Attributes attr = ctx.getAttributes(“uid=mborn,ou=Users”);
System.out.println(“Mborn’s name is ” + attr.get(“cn”).get());
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
First thing that happens is creating an DirContext. For this an instance of Hashtable is passed to the InitialDirContext. The hashtable sets up the Context that is used and where it will connect. The URL has two parts, the address to the server and the directory in the server. All of the entries that are written to or read from are assumed to be in that directory. The next line returns the attributes for the entry that has a user id of mborn and is in the users organizational unit. The System.out line retrieves the “cn” or common name from the entry and prints it out to the screen. All of this is wrapped in a try-catch block in case a NamingException is thrown. This is the basic query and retrieve from a LDAP server and is most of what happens.
While JNDI is excellent at pulling attributes from a LDAP server, its real power comes from when one starts storing Java objects on the server. That will be discussed on the next entry.
Links to resources used for this article:
JNDI Tutorial
Mastering OpenLDAP
The Apache Directory Project