Ensar Basri Kahveci

overly distributed

Integrating Spring Security with LDAP

Posted at — Sep 29, 2011

java - ldap - spring - spring security 

To integrate Spring Security with Ldap, add the dependency to your build path first. You don’t have to define the second dependency, it is for using the latest version of spring ldap core.

	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-ldap</artifactId>
		<version>3.0.5</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.ldap</groupId>
		<artifactId>spring-ldap-core</artifactId>
		<version>1.3.1.RELEASE</version>
	</dependency>

Spring LDAP’s LdapTemplate makes doing LDAP operations too much easy. But for simple authentication mechanism, you don’t need to use it actually. Although I will talk about LdapTemplate a little bit.

I put the LDAP - related Spring Security config xml below.

	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"  xmlns:sec="http://www.springframework.org/schema/security">

		<sec:http auto-config="false" >
			<!-- ... -->
		</sec:http>

		<sec:ldap-server url="http://localhost:389" manager-dn="dc=companyname,dc=foo,dc=bar" manager-password="yourNot123456Password" />

		<sec:authentication-manager>
			<sec:ldap-authentication-provider user-search-filter="(uid={0})" user-context-mapper-ref="ldapContextMapperImpl"/>
		</sec:authentication-manager>
		<!-- define ldapContextMapperImpl here or annotate your implementation with @Component("ldapContextMapperImpl") -->
	</beans>

3 lines of configuration are enough to integrate it with LDAP basically. To modify the integration details, there are also various configuration options.

Let me explain the configuration above.

<sec:ldap-server url="..." manager-dn="..." manager-password="..." />

It defines the server the authentication takes place. Take your url, directory name, password parameters from your system staff (we did it that way) or configure it by yourself if you are familiar with LDAP.

<sec:ldap-authentication-provider user-search-filter="(uid={0})" user-context-mapper-ref="ldapContextMapperImpl"/>

ldap-authentication-provider definition uses (uid={0}) as search filter, and our special UserDetailsContextMapper implementation. With our ldapContextMapperImpl, we populate our UserDetails object with successfully authenticated user info. It has one method with signature as follows:

public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection authority);

It gives you the authenticated username, authorities and ctx object. Actually, we didn’t need the ctx object. username was enough for us to load authorities from a different data source.

If you want to make operations on your LDAP server, configure a LdapTemplate in your security context. LdapTemplate needs a ContextSource implementation. Configure your ContextSource with org.springframework.ldap.core.support.LdapContextSource and pass it to LdapTemplate like:

	<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
    	<property name="url" value="ldap://localhost:389" />
	    <property name="base" value="dc=javachap,dc=com" />
    	<property name="userDn" value="cn=Manager,dc=javachap,dc=com" />
	    <property name="password" value="mypassword" />
	</bean>

	<bean id="ldapTemplate">
    	<constructor-arg ref="contextSource" />
	</bean>

Now you can do a lot of operations on your LdapTemplate. Here is an example:

Filter ldapFilter = new EqualsFilter("uid", username));
ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);

You can also use AndFilter, LikeFilter, etc to make operations with LdapTemplate, for example try ldapTemplate.search() method.

To make things work, we read a bunch of docs and tried a lot of implementation classes I did not mention here like LdapAuthenticator implementations, FilterBasedLdapUserSearch. So I got a little bit familiar with them. If you want to make a detail configuration for Ldap integration, I recommend you to read the docs here. If you have questions, I will try to answer them. There are also a lot of useful blog posts about the subject which you can find with a simple Google search.

Finally, I thank to Berkay Aktan. We made some kind of pair programming for various Spring Security tasks for a couple of days. I learned a lot of things from him and we had great fun :)

comments powered by Disqus