Spring Active Directory Configuration that works…

Authentication and authorization with Active directory and Spring is tough…tougher than it should be. Trying to find working examples is also very difficult, so once I had a working version, I decided to share it.

You really don’t need any custom classes to do this. Spring has all the necessary built-in objects. In order to run this, you will need Spring 3.0 and Spring Security 3.0.

The example below doesn’t take full advantage of the namespace configuration. I just didn’t have the time to get that all put together. If you have a cleaner “working” example, please post as a comment, so others can learn by your example.

<beans xmlns="http://www.springframework.org/schema/beans&quot;
xmlns:context=”http://www.springframework.org/schema/context&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:aop=”http://www.springframework.org/schema/aop&#8221;
xmlns:security=”http://www.springframework.org/schema/security&#8221;
xmlns:tx=”http://www.springframework.org/schema/tx&#8221;
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd”&gt;

<!–
constructor = LDAP domain name userDn = user id used to query the
directory password = password for managerDn baseEnvironmentProperties
= additional ldap environment properties
–>
<bean id="initialDirContextFactory"
class=”org.springframework.security.ldap.DefaultSpringSecurityContextSource”>
<constructor-arg
value=”ldap://adserver:389/dc=domain,dc=com” />
<property name="userDn"
value=”CN=cipldap,OU=Service Accounts,OU=Organizational Units,DC=domain,DC=com” />

follow

<!–
Used to search active directory for the user id of the user attempting
to login to the system. 1. Instead of binding directly, Acegi uses the
filter to find a matching user 2. If no user is found, that’s a
failure. 3. If a user is found, takes that users DN and tries to bind
using it 4. Success to bind means that we are okay, failure means
incorrect password constructor 0 = BaseDN for user search constructor
1 = Filter statement for user id lookup constructor 2 = initial
context factory defined above searchSubtree = search the subtrees
beneath BaseDN.
–>
<bean id="userSearch"
class=”org.springframework.security.ldap.search.FilterBasedLdapUserSearch”>

<!–
Peform the LDAP user bind using the context factory and user search

constructor = initial context factory defined above userSearch =
userSearch defined above
–>
<bean id="bindAuthenticator"
class=”org.springframework.security.ldap.authentication.BindAuthenticator”>

<!–
Used for authorization. Populate the user with a set of roles based
upon AD groups. constructor 0 = context factory constructor 1 = BaseDN
for groups groupRoleAttribute = attribute used for role names
–>
<bean id="authoritiesPopulator"
class=”org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator”>

<!–
LDAP Authentication Provider uses the bindAuthenticator and
authoritiesPopulator to authenticate the user and populate the user
object with roles based upon Active Directory groups.
–>
<bean id="ldapAuthProvider"
class=”org.springframework.security.ldap.authentication.LdapAuthenticationProvider”>


You can use this section to map your groups and roles from your application to groups and roles in LDAP. I just restated the same ones that were stored in my Active Directory server.

<bean id="userDetailsContextMapper"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsMapper”>

ROLE_PROJECT_INQUIRY
ROLE_PROJECT_UPDATE

<bean id="userDetailsService"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsService”>

<security:authentication-provider
ref=”ldapAuthProvider” user-service-ref=”userService” />

Once your configuration is written, you can now access your user and group information via Spring.
@RequestMapping(value = "/print",
method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public String print() throws Exception {

StringBuilder sb = new StringBuilder();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {

UserDetails userDetails = (UserDetails) principal;

sb.append("User: " + userDetails.getUsername());
sb.append("\nPassword: " + userDetails.getPassword());

List authorities =userDetails.getAuthorities();

for (GrantedAuthority grantedAuthority : authorities) {

sb.append("\nAuthority: " + grantedAuthority.getAuthority());
log.debug("Authority: " + grantedAuthority.getAuthority());

}

log.debug(sb.toString());

}

return sb.toString();
}

Also, now that you have your setup, you can use security annotations and intercept-url elements in the config to lock down your application. It took me a while to get all of this working correctly. I’d much rather have authenticated against a database table instead of Active Directory and spared myself some of the pain.

About these ads

About Chris Hardin
Chief Architect at Doozer Software in Birmingham, Al. I specialize in Java and .NET Architecture, Ajax Frameworks and Mobile Architecture with iOS and Android.

2 Responses to Spring Active Directory Configuration that works…

  1. Wissam says:

    Great post! Indeed finding the correct settings for AD is a pain.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: