tags:

views:

2838

answers:

9
+7  Q: 

LDAP Java library

We are using J2EE to develop a security product that relies on LDAP for authentication and role-based user management.

The team has implemented this using the JNDI but we have run into various pitfalls. I am looking for an LDAP API that handles all the low-level details and satisfies the following requirements:

  1. LDAP User authentication and Authorization
  2. Good performance (even with large and slow LDAP servers)
  3. Support the main LDAP flavors (AD, Novell eDirectory etc.)

Can anyone recommend an open source or commercial package?

+3  A: 

http://www.openldap.org/jldap/

Dmitry Khalatov
+5  A: 

I've used Spring's LDAP modules. I think they make programming with LDAP as easy as using JDBC. If you're using Spring, I recommend them highly. If you're not, there's value in learning it.

duffymo
+8  A: 

LDAP itself is already providing a pretty high level abstraction for directory servers, I haven't seen many libraries that provide a further abstraction on top of that. I have written my own little library to enable my own application to talk to LDAP servers (in my case, also an Active Directory server).

The java.naming.directory package is where the interesting stuff is. Connecting to an LDAP server is really not too hard...

// set properties for our connection and provider
Properties properties = new Properties();
properties.put( Context.INITIAL_CONTEXT_FACTORY, 
  "com.sun.jndi.ldap.LdapCtxFactory" );
properties.put( Context.PROVIDER_URL, "ldap://myserver.somewhere.com:389"; );
properties.put( Context.REFERRAL, "ignore" );

// set properties for authentication
properties.put( Context.SECURITY_PRINCIPAL, "User Name" );
properties.put( Context.SECURITY_CREDENTIALS, "password" );

InitialDirContext context = new InitialDirContext( properties );

Running searches against the directory isn't that much more difficult.

// Create the search controls
SearchControls searchCtls = new SearchControls();

// Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

// specify the LDAP search filter, just users
String searchFilter = "(&(objectClass=user)( cn=Joe Someone))";

// Specify the attributes to return
String returnedAtts[]={"memberOf"};
searchCtls.setReturningAttributes(returnedAtts);

NamingEnumeration answer = context.search( "dc=com,dc=somewhere", searchFilter, 
  searchCtls );

From there, authentication is very easy: the last line above will throw a NamingException is the username and password are not valid credentials.

I have used the Acegi Security library to good effect with a couple applications, getting Acegi to work with an LDAP backend is pretty straightforward; this may be the more high level solution you are looking for.

Miles
I'd accept your answer, since your code worked out of the box for me.
boutta
+1  A: 

I have used Netscape LDAP SDK for Java in place of JNDI on a couple of occasions (e.g. LDAP Maven Plugin). But that was because I needed to import/export records using LDIF and DSML.

For web applications that need to manage entries in the directory I have used Spring LDAP. This is a layer on top of JNDI. One of my colleagues implemented caching using Spring AOP to improve the performance.

However, I believe the problem is most likely to in the design of your directory and the starting point that you use for your directory searches and look ups. Also make sure you use filters to avoid returning back all the attributes for an object. You are probably only interested in a small subset of what may be available.

You might also want to consider using a higher level framework for your security requirements. I generally use Spring Security for dealing with authorization and access control when developing web applications. However, whenever possible I prefer to do the authentication on the web server. If you are using Apache HTTPD then you can used the mod_ldap module.

bmatthews68
A: 

Consider NOT using the Java APIs and instead checking out ArisID and its abstraction layer for identity...

jm04469
A: 

Netscapes LDAP API is nice, easy to use, but JNDI should replace it.

What pitfalls did you have with JNDI? You may want to stay with JNDI and just get help on the pitfalls.

Once you have JNDI set up it isn't too hard to use, but the initial setup is a bit of a pain. :)

JNDI is more flexible than the Netscape API. I haven't tried Spring's implementation, but if you are going to use Spring for other parts of an application it would be a good choice to use it.

The LDAP server is where you will find the slowdown, not in the API. OpenLDAP has been too slow for me, when updating, but I had to put over 80k users into it, but Sun's IPlanet worked well. The various APIs won't show a slowdown as they are much faster than updating the database.

James Black
+1  A: 

Check out http://code.google.com/p/object-ldap-mapping/ It is based on Spring LDAP but provides API similar to JPA

Paul Szulc
A: 

You can even try with jLDAPBeans (http://jldapbeans.sf.net), it follows same approach than JPA building an abstraction layer over JNDI, it doesn't depends on Spring and objects are defined as interfaces, an ldap object loaded with this library implements as many "entity interfaces" as objectClasses are defined in the directory.

it has an old experimental version (0.1) and a newer one (0.5) it's being implemented with a lot of refactoring in order to offer the same things as a full JPA implementation (caching, transactions, etc). The problem is that last version is not stable so you need to work with the experimental version.

Alonso
+1  A: 

Actually, todays, there is only 4 relevant Java LDAP SDK. Other are not supported anymore and/or not updated for Java 5 and higher:

  • JNDI LDAP is still the "standard" choice, but you should use it if and only if you are FORCE to (for historical reasons, for example). JNDI LDAP is just a pain to use: almost anything you want to do with it is hard, even if LDAP itself is a really, really simple protocol, and I don't even talk about LDAP more advance features... But sometime, you just don't have any choice;
  • Spring LDAP http://www.springsource.org/ldap ; I would say use it if and only if your application is already full Spring, and you are really used to the Spring "template" abstraction. But per se, Spring LDAP is just a layer on top of JNDI, and so it doesn't bring better performances or other LDAP specific features ;
  • the ongoing effort to build a new default, common LDAP API, by ApacheDS and OpenDS people : http://cwiki.apache.org/confluence/display/LDAPAPI/Index ; it is a beginning, and not ready for production use, but you should keep an eye on that project ;
  • and finally, THE SDK to use right now, in place JNDI LDAP: UnboundID LDAP SDK http://www.unboundid.com/products/ldapsdk/ ; Simple for simple use cases but nevertheless full support of LDAP, good performances, nice new features added regularly (the 2.0 add a object/entry mapping&persistence API), etc.

So, if you have only one to keep in mind, just get UnboundID LDAP SDK.

fanf42