May 03, 2007

Getting started with LDAP on Java

Your boss asked you to do some research on using LDAP with Java. Its friday morning and you're already in weekend mode. You fire up your favourite search engine (google) and what you get are complicated articles and tutorials which could take you days to go through. If this is you, read on.

To play with LDAP you need an LDAP server. Rather than waste an morning compiling and installing one from OpenLDAP, you could :
1. Use someone elses LDAP server
2. Get a trial copy of a simple LDAP server

I got a simple LDAP server to install locally because I wanted to add LDAP records and I need a user account to do that. Public LDAP servers usually will not allow you to do that.

Since you're coding with Java, you need a Java compiler. I fire up my trusty Netbeans. You can use whatever you want. We're only going to code a main method anyway.

Once the LDAP server is installed and running, there aren't any entries inside. So the first thing to do is to add the entries. If you're only interested in searching the LDAP directory, skip down a few paragraphs.

First your imports. The IDE takes care of this for me but here's the list. We're using JNDI packages and it should be in JDKs 1.4 and higher.

import java.util.Properties;
import javax.naming.*;
import javax.naming.directory.*;


The connection settings go inside a properties object.

Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
props.setProperty(Context.REFERRAL, "ignore");
props.setProperty(Context.SECURITY_AUTHENTICATION, "simple");


Host name goes here


props.setProperty(Context.PROVIDER_URL, "ldap://localhost:389");


Username and password goes here. If you're using a public LDAP server, these may be blank or have some default value. It depends.....

props.setProperty(Context.SECURITY_PRINCIPAL, "cn=manager,dc=example,dc=com");
props.setProperty(Context.SECURITY_CREDENTIALS, "");


Note above. The username is manager. the password is blank. The string security principal describes the user being from directory context example.com. The order is important. You may need to change the dc appropriately on public servers.

When its all set up, just call the statement below to get the initial context.

ctx = new InitialDirContext(props);

This is like a pointer to a directory. With the context, you can work on the LDAP. First we create a set of attributes. Basically we're adding a record which conforms to a schema. A schema defines what fields an object can and must have. The example we will use is netwinperson. A schema is also known as an object class. The netwinperson defines a person. It has two mandatory fields cn (Common name) and sn (Surname) and a bunch of optional fields. In Java its possible to create an object which maps to this schema. We'll reserve that for future blog entries. Right now, we'll create a set of attributes which we will assign a name.

Attribute cn = new BasicAttribute("cn", "Scott");
Attribute sn = new BasicAttribute("sn", "Smith");
Attribute mail = new BasicAttribute("mail", "newuser@foo.com");


Next we must have another attribute for the object class. Attributes have names and one or more values.

Attribute oc = new BasicAttribute("objectClass");
oc.add("netwinperson");


Now we create the entry which is a collection of attributes

Attributes entry = new BasicAttributes();
entry.put(oc);
entry.put(cn);
entry.put(sn);
entry.put(mail);


Now we add the entry.

try {
ctx.bind("cn=Scott,dc=example,dc=com",null,entry);
} catch (NamingException ex) {
ex.printStackTrace();
}


Here is where we search the LDAP for the entry we just created.

SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);String filter = "cn=Scott";
String BASE_SEARCH = "dc=example,dc=com";
NamingEnumeration results = ctx.search(BASE_SEARCH, filter, constraints);


Note our search filter uses the cn attribute. We can use wildcards here. Note also the BASE_SEARCH tell us where to start searching. In this case from the root which is example.com. Our results appear in the variable results. We can check this enumeration object for any matches, but I just output what I know is there.

System.out.println(results.next().toString());


This outputs the entire entry. We can drill down to output individual entries but I'm only here to get you started.

Since we're done, we close the connection like a good programmer should.

ctx.close();

I'm no expert on LDAP. What I write here is what I found online in the course of one friday morning. But this code should get you started in less than an hour.

No comments: