Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

LDAP and JNDI: Together forever

Learn how LDAP and JNDI combine to form a powerful directory and Java object storage facility

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
The Lightweight Directory Access Protocol (LDAP), which traces its roots to the X.500 protocol, was developed in the early 1990s as a standard directories protocol. LDAP defines how clients should access data on the server, not how that data is stored on the server. This allows LDAP to become a frontend to any type of data store.

(Note: To download this article's complete source code, see the Resources section below.)

LDAP's basic structure is based on a simple information tree metaphor called a directory information tree (DIT). Each leaf in the tree is an entry; the first or top-level entry is the root entry. An entry includes a distinguished name (DN) and any number of attribute/value pairs. The DN, which is the name of an entry, must be unique. It shows the relationship between the entry and the rest of the DIT in a manner similar to the way in which a file's full path name shows its relationship with the rest of the files in a filesystem. While a path to a file reads left to right, a DN, in contrast, reads from right to left. Here is an example of an DN:

uid=styagi,ou=people,o=myserver.com


The leftmost part of the DN, called a relative distinguished name (RDN), is made up of an attribute/value pair. In the above example, this pair would be uid=styagi. LDAP attributes often use mnemonics, some examples of which are listed in Table 1.

o Organization
ou Organizational unit
cn Common name
sn Surname
givenname First name
uid Userid
dn Distinguished name
mail Email address
Table 1. Some common LDAP attributes


Information about attributes, attribute matching rules, and relationships between objectclasses are defined in the server's schema. Any attribute can have one or more values, depending on how it is defined the schema. A user, for example, can have more than one email address. There is also a special attribute called an objectclass that specifies the required and allowed attributes for a particular entry. Like objects in Java, objectclasses in LDAP can be extended to retain existing attributes and add new ones.

A naming service associates names with objects and finds objects based on their given names. (The RMI registry is a good example of a naming service.) Many naming services are extended with a directory service. While a naming service allows a lookup of an object based on its name, a directory service also allows such objects to have attributes. As a result, with a directory service we can look up an object's attributes or search for objects based on their attributes.

So where does JNDI fit into this LDAP jargon? JNDI does for LDAP what JDBC does for Oracle -- it provides a standard API for interacting with naming and directory services using a service provider interface (SPI), which is analogous to an JDBC driver. LDAP is a standard way to provide access to directory information. JNDI gives Java applications and objects a powerful and transparent interface to access directory services like LDAP. Table 2 below outlines common LDAP operations and their JNDI equivalents. (For a detailed look at the JNDI specification, see Resources.)

Operation What it does JNDI equivalent
Search Search directory for matching directory entries DirContext.search()
Compare Compare directory entry to a set of attributes DirContext.search()
Add Add a new directory entry DirContext.bind(), DirContext.createSubcontext()
Modify Modify a particular directory entry DirContext.modifyAttributes()
Delete Delete a particular directory entry Context.unbind(), Context.destroySubcontext()
Rename Rename or modify the DN Context.rename()
Bind Start a session with an LDAP server new InitialDirContext()
Unbind End a session with an LDAP server Context.close()
Abandon Abandon an operation previously sent to the server Context.close(), NamingEnumneration.close()
Extended Extended operations command LdapContext.extendedOperation()
Table 2. Common LDAP operations and JNDI equivalents


Manipulate objects in the LDAP server

Let's cut to the chase and see how to manipulate objects in the LDAP server. The standard LDAP operations include:

  • Connect to the server
  • Bind to the server (think of this as authentication)
  • Add new entries in the LDAP server
  • Modify an entry
  • Delete an entry
  • Search the server for an entry


We'll examine each of these steps in the sections below, with examples.

Before executing the examples, you will need to install the LDAP server, the JNDI classes, and (unless you want to disable schema checking) the Java schema. You can find install information in the JNDI zip file's schema directory. Our examples use Netscape Directory Server 4.1 and JDK 2. (To install these packages, see Resources.)

Connect to the server

To connect to the server, you must obtain a reference to an object that implements the DirContext interface. In most applications, this is done by using an InitialDirContext object that takes a Hashtable as an argument. The Hashtable contains various entries, such as the hostname, port, and JNDI service provider classes to use:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389");
DirContext ctx = new InitialDirContext(env);


Bind to the Server

Once connected, the client may need to authenticate itself; this process is also known as binding to the server. (Be aware that the word binding can also refer to the act of adding something to the directory.)

In LDAP version 2, all clients had to authenticate while connecting, but version 3 defaults to anonymous and, if the default values are used, the connections are anonymous as well. LDAP servers maintain rights using access control lists (ACLs) that determine what particular access is available to an entry by an application. LDAP supports three different security types:

  • Simple: Authenticates fast using plain text usernames and passwords.
  • SSL: Authenticates with SSL encryption over the network.
  • SASL: Uses MD5/Kerberos mechanisms. SASL is a simple authentication and security layer-based scheme


The client authenticates itself to the server by specifying values for different environment variables in the Context interface, as seen below:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (10)
Login
Forgot your account info?

binding issueBy Anonymous on November 3, 2009, 3:02 pmDoes anyone know how you can bind to the directory using JNDI, but without knowing the credentials needed for authentication? In other words, I can't assume that...

Reply | Read entire comment

Nice ArticleBy Anonymous on October 11, 2009, 12:35 pmSplendid work..Thanks.. :D

Reply | Read entire comment

great job, this article has been very helpful.By Anonymous on October 6, 2009, 2:53 pmgreat job, this article has been very helpful.

Reply | Read entire comment

Good oneBy Anonymous on August 18, 2009, 10:34 amGood job.

Reply | Read entire comment

Well written articleBy Anonymous on June 23, 2009, 11:22 amThanks a lot!

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • Example code
  • Resources necessary to run the examples
  • Todd Sundsted's How To Java LDAP series
  • SunWorld's LDAP series
  • Other important LDAP resources