org.acegisecurity.providers.ldap
Class LdapAuthenticationProvider

java.lang.Object
  extended by org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider
      extended by org.acegisecurity.providers.ldap.LdapAuthenticationProvider
All Implemented Interfaces:
AuthenticationProvider, org.springframework.beans.factory.InitializingBean, org.springframework.context.MessageSourceAware

public class LdapAuthenticationProvider
extends AbstractUserDetailsAuthenticationProvider

An AuthenticationProvider implementation that provides integration with an LDAP server.

There are many ways in which an LDAP directory can be configured so this class delegates most of its responsibilites to two separate strategy interfaces, LdapAuthenticator and LdapAuthoritiesPopulator.

LdapAuthenticator

This interface is responsible for performing the user authentication and retrieving the user's information from the directory. Example implementations are BindAuthenticator which authenticates the user by "binding" as that user, and PasswordComparisonAuthenticator which performs a comparison of the supplied password with the value stored in the directory, either by retrieving the password or performing an LDAP "compare" operation.

The task of retrieving the user attributes is delegated to the authenticator because the permissions on the attributes may depend on the type of authentication being used; for example, if binding as the user, it may be necessary to read them with the user's own permissions (using the same context used for the bind operation).

LdapAuthoritiesPopulator

Once the user has been authenticated, this interface is called to obtain the set of granted authorities for the user. The DefaultLdapAuthoritiesPopulator can be configured to obtain user role information from the user's attributes and/or to perform a search for "groups" that the user is a member of and map these to roles.

A custom implementation could obtain the roles from a completely different source, for example from a database.

Configuration

A simple configuration might be as follows:
    <bean id="initialDirContextFactory" class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory">
      <constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/>
      <property name="managerDn"><value>cn=manager,dc=acegisecurity,dc=org</value></property>
      <property name="managerPassword"><value>password</value></property>
    </bean>

    <bean id="ldapAuthProvider" class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
      <constructor-arg>
        <bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
          <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
          <property name="userDnPatterns"><list><value>uid={0},ou=people</value></list></property>
        </bean>
      </constructor-arg>
      <constructor-arg>
        <bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
          <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
          <constructor-arg><value>ou=groups</value></constructor-arg>
          <property name="groupRoleAttribute"><value>ou</value></property>
        </bean>
      </constructor-arg>
    </bean>

This would set up the provider to access an LDAP server with URL ldap://monkeymachine:389/dc=acegisecurity,dc=org. Authentication will be performed by attempting to bind with the DN uid=<user-login-name>,ou=people,dc=acegisecurity,dc=org. After successful authentication, roles will be assigned to the user by searching under the DN ou=groups,dc=acegisecurity,dc=org with the default filter (member=<user's-DN>). The role name will be taken from the "ou" attribute of each match.

The authenticate method will reject empty passwords outright. LDAP servers may allow an anonymous bind operation with an empty password, even if a DN is supplied. In practice this means that if the LDAP directory is configured to allow unauthenitcated access, it might be possible to authenticate as any user just by supplying an empty password. More information on the misuse of unauthenticated access can be found in draft-ietf-ldapbis-authmeth-19.txt.

Version:
$Id: LdapAuthenticationProvider.java 1995 2007-08-30 21:12:16Z luke_t $
Author:
Luke Taylor
See Also:
BindAuthenticator, DefaultLdapAuthoritiesPopulator

Field Summary
 
Fields inherited from class org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider
hideUserNotFoundExceptions, messages
 
Constructor Summary
LdapAuthenticationProvider(LdapAuthenticator authenticator)
          Creates an instance with the supplied authenticator and a null authorities populator.
LdapAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator)
          Create an instance with the supplied authenticator and authorities populator implementations.
 
Method Summary
protected  void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
          Allows subclasses to perform any additional checks of a returned (or cached) UserDetails for a given authentication request.
protected  UserDetails createUserDetails(LdapUserDetails ldapUser, String username, String password)
          Creates the final UserDetails object that will be returned by the provider once the user has been authenticated.
protected  LdapAuthoritiesPopulator getAuthoritiesPopulator()
           
 boolean isIncludeDetailsObject()
           
protected  UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
          Allows subclasses to actually retrieve the UserDetails from an implementation-specific location, with the option of throwing an AuthenticationException immediately if the presented credentials are incorrect (this is especially useful if it is necessary to bind to a resource as the user in order to obtain or generate a UserDetails).
 void setIncludeDetailsObject(boolean includeDetailsObject)
           
 
Methods inherited from class org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider
afterPropertiesSet, authenticate, createSuccessAuthentication, doAfterPropertiesSet, getPostAuthenticationChecks, getPreAuthenticationChecks, getUserCache, isForcePrincipalAsString, isHideUserNotFoundExceptions, setForcePrincipalAsString, setHideUserNotFoundExceptions, setMessageSource, setPostAuthenticationChecks, setPreAuthenticationChecks, setUserCache, supports
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

LdapAuthenticationProvider

public LdapAuthenticationProvider(LdapAuthenticator authenticator,
                                  LdapAuthoritiesPopulator authoritiesPopulator)
Create an instance with the supplied authenticator and authorities populator implementations.

Parameters:
authenticator - the authentication strategy (bind, password comparison, etc) to be used by this provider for authenticating users.
authoritiesPopulator - the strategy for obtaining the authorities for a given user after they've been authenticated.

LdapAuthenticationProvider

public LdapAuthenticationProvider(LdapAuthenticator authenticator)
Creates an instance with the supplied authenticator and a null authorities populator. In this case, the authorities must be mapped from the user context.

Parameters:
authenticator - the authenticator strategy.
Method Detail

getAuthoritiesPopulator

protected LdapAuthoritiesPopulator getAuthoritiesPopulator()

additionalAuthenticationChecks

protected void additionalAuthenticationChecks(UserDetails userDetails,
                                              UsernamePasswordAuthenticationToken authentication)
                                       throws AuthenticationException
Description copied from class: AbstractUserDetailsAuthenticationProvider
Allows subclasses to perform any additional checks of a returned (or cached) UserDetails for a given authentication request. Generally a subclass will at least compare the Authentication.getCredentials() with a UserDetails.getPassword(). If custom logic is needed to compare additional properties of UserDetails and/or UsernamePasswordAuthenticationToken, these should also appear in this method.

Specified by:
additionalAuthenticationChecks in class AbstractUserDetailsAuthenticationProvider
Parameters:
userDetails - as retrieved from the AbstractUserDetailsAuthenticationProvider.retrieveUser(String, UsernamePasswordAuthenticationToken) or UserCache
authentication - the current request that needs to be authenticated
Throws:
AuthenticationException - AuthenticationException if the credentials could not be validated (generally a BadCredentialsException, an AuthenticationServiceException)

createUserDetails

protected UserDetails createUserDetails(LdapUserDetails ldapUser,
                                        String username,
                                        String password)
Creates the final UserDetails object that will be returned by the provider once the user has been authenticated.

The LdapAuthoritiesPopulator will be used to create the granted authorites for the user.

Can be overridden to customize the creation of the final UserDetails instance. The default will merge any additional authorities retrieved from the populator with the propertis of original ldapUser object and set the values of the username and password.

Parameters:
ldapUser - The intermediate LdapUserDetails instance returned by the authenticator.
username - the username submitted to the provider
password - the password submitted to the provider
Returns:
The UserDetails for the successfully authenticated user.

retrieveUser

protected UserDetails retrieveUser(String username,
                                   UsernamePasswordAuthenticationToken authentication)
                            throws AuthenticationException
Description copied from class: AbstractUserDetailsAuthenticationProvider
Allows subclasses to actually retrieve the UserDetails from an implementation-specific location, with the option of throwing an AuthenticationException immediately if the presented credentials are incorrect (this is especially useful if it is necessary to bind to a resource as the user in order to obtain or generate a UserDetails).

Subclasses are not required to perform any caching, as the AbstractUserDetailsAuthenticationProvider will by default cache the UserDetails. The caching of UserDetails does present additional complexity as this means subsequent requests that rely on the cache will need to still have their credentials validated, even if the correctness of credentials was assured by subclasses adopting a binding-based strategy in this method. Accordingly it is important that subclasses either disable caching (if they want to ensure that this method is the only method that is capable of authenticating a request, as no UserDetails will ever be cached) or ensure subclasses implement AbstractUserDetailsAuthenticationProvider.additionalAuthenticationChecks(UserDetails, UsernamePasswordAuthenticationToken) to compare the credentials of a cached UserDetails with subsequent authentication requests.

Most of the time subclasses will not perform credentials inspection in this method, instead performing it in AbstractUserDetailsAuthenticationProvider.additionalAuthenticationChecks(UserDetails, UsernamePasswordAuthenticationToken) so that code related to credentials validation need not be duplicated across two methods.

Specified by:
retrieveUser in class AbstractUserDetailsAuthenticationProvider
Parameters:
username - The username to retrieve
authentication - The authentication request, which subclasses may need to perform a binding-based retrieval of the UserDetails
Returns:
the user information (never null - instead an exception should the thrown)
Throws:
AuthenticationException - if the credentials could not be validated (generally a BadCredentialsException, an AuthenticationServiceException or UsernameNotFoundException)

isIncludeDetailsObject

public boolean isIncludeDetailsObject()

setIncludeDetailsObject

public void setIncludeDetailsObject(boolean includeDetailsObject)


Copyright © 2004-2010 Interface21, Inc. All Rights Reserved.