Browse Source

SEC-558: Combine user mapping implementations into a single interface and make more use of DirContextOperations in SS LDAP APIs.

2.0.x
Luke Taylor 19 years ago
parent
commit
8a35f7da75
  1. 6
      core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java
  2. 4
      core/src/main/java/org/acegisecurity/ldap/LdapUtils.java
  3. 22
      core/src/main/java/org/acegisecurity/ldap/SpringSecurityLdapTemplate.java
  4. 19
      core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java
  5. 57
      core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java
  6. 3
      core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java
  7. 6
      core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java
  8. 13
      core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java
  9. 21
      core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java
  10. 7
      core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java
  11. 30
      core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java
  12. 48
      core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java
  13. 71
      core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java
  14. 14
      core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java
  15. 52
      core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java
  16. 31
      core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java
  17. 10
      core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java
  18. 35
      core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java
  19. 60
      core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java
  20. 7
      core/src/test/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapperTests.java

6
core/src/main/java/org/acegisecurity/ldap/LdapUserSearch.java

@ -15,7 +15,7 @@
package org.acegisecurity.ldap; package org.acegisecurity.ldap;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -37,7 +37,7 @@ public interface LdapUserSearch {
* *
* @param username the login name supplied to the authentication service. * @param username the login name supplied to the authentication service.
* *
* @return an LdapUserDetailsImpl object containing the user's full DN and requested attributes. * @return a DirContextOperations object containing the user's full DN and requested attributes.
*/ */
LdapUserDetails searchForUser(String username); DirContextOperations searchForUser(String username);
} }

4
core/src/main/java/org/acegisecurity/ldap/LdapUtils.java

@ -26,6 +26,7 @@ import java.io.UnsupportedEncodingException;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.Name;
/** /**
@ -73,8 +74,7 @@ public final class LdapUtils {
* *
* @throws NamingException any exceptions thrown by the context are propagated. * @throws NamingException any exceptions thrown by the context are propagated.
*/ */
public static String getRelativeName(String fullDn, Context baseCtx) public static String getRelativeName(String fullDn, Context baseCtx) throws NamingException {
throws NamingException {
String baseDn = baseCtx.getNameInNamespace(); String baseDn = baseCtx.getNameInNamespace();

22
core/src/main/java/org/acegisecurity/ldap/SpringSecurityLdapTemplate.java

@ -27,6 +27,7 @@ import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.AttributesMapper; import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.AttributesMapperCallbackHandler; import org.springframework.ldap.core.AttributesMapperCallbackHandler;
import org.springframework.ldap.core.DirContextOperations;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -41,6 +42,7 @@ import javax.naming.NamingEnumeration;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NameClassPair; import javax.naming.NameClassPair;
import javax.naming.Name;
import javax.naming.directory.Attribute; import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes; import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
@ -136,22 +138,19 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
* Composes an object from the attributes of the given DN. * Composes an object from the attributes of the given DN.
* *
* @param dn the directory entry which will be read * @param dn the directory entry which will be read
* @param mapper maps the attributes to the required object
* @param attributesToRetrieve the named attributes which will be retrieved from the directory entry. * @param attributesToRetrieve the named attributes which will be retrieved from the directory entry.
* *
* @return the object created by the mapper * @return the object created by the mapper
*/ */
public Object retrieveEntry(final String dn, final ContextMapper mapper, final String[] attributesToRetrieve) { public DirContextOperations retrieveEntry(final String dn, final String[] attributesToRetrieve) {
return executeReadOnly(new ContextExecutor() { return (DirContextOperations) executeReadOnly(new ContextExecutor() {
public Object executeWithContext(DirContext ctx) throws NamingException { public Object executeWithContext(DirContext ctx) throws NamingException {
Attributes attrs = ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve); Attributes attrs = ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve);
// Object object = ctx.lookup(LdapUtils.getRelativeName(dn, ctx)); // Object object = ctx.lookup(LdapUtils.getRelativeName(dn, ctx));
DirContextAdapter ctxAdapter = new DirContextAdapter(attrs, new DistinguishedName(dn)); return new DirContextAdapter(attrs, new DistinguishedName(dn));
return mapper.mapFromContext(ctxAdapter);
} }
}); });
} }
@ -227,17 +226,15 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
* @param base * @param base
* @param filter * @param filter
* @param params * @param params
* @param mapper
* *
* @return the object created by the mapper from the matching entry * @return the object created by the mapper from the matching entry
* *
* @throws IncorrectResultSizeDataAccessException if no results are found or the search returns more than one * @throws IncorrectResultSizeDataAccessException if no results are found or the search returns more than one
* result. * result.
*/ */
public Object searchForSingleEntry(final String base, final String filter, final Object[] params, public DirContextOperations searchForSingleEntry(final String base, final String filter, final Object[] params) {
final ContextMapper mapper) {
return executeReadOnly(new ContextExecutor() { return (DirContextOperations) executeReadOnly(new ContextExecutor() {
public Object executeWithContext(DirContext ctx) public Object executeWithContext(DirContext ctx)
throws NamingException { throws NamingException {
@ -269,10 +266,7 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
dn.append(nameInNamespace); dn.append(nameInNamespace);
} }
DirContextAdapter ctxAdapter = new DirContextAdapter( return new DirContextAdapter(searchResult.getAttributes(), new DistinguishedName(dn.toString()));
searchResult.getAttributes(), new DistinguishedName(dn.toString()));
return mapper.mapFromContext(ctxAdapter);
} }
}); });
} }

19
core/src/main/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearch.java

@ -20,9 +20,6 @@ import org.acegisecurity.ldap.SpringSecurityLdapTemplate;
import org.acegisecurity.ldap.LdapUserSearch; import org.acegisecurity.ldap.LdapUserSearch;
import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -32,6 +29,7 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextOperations;
import javax.naming.directory.SearchControls; import javax.naming.directory.SearchControls;
@ -53,7 +51,6 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch {
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
private ContextSource initialDirContextFactory; private ContextSource initialDirContextFactory;
private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper();
/** /**
* The LDAP SearchControls object used for the search. Shared between searches so shouldn't be modified * The LDAP SearchControls object used for the search. Shared between searches so shouldn't be modified
@ -105,7 +102,7 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch {
* *
* @throws UsernameNotFoundException if no matching entry is found. * @throws UsernameNotFoundException if no matching entry is found.
*/ */
public LdapUserDetails searchForUser(String username) { public DirContextOperations searchForUser(String username) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Searching for user '" + username + "', with user search " logger.debug("Searching for user '" + username + "', with user search "
+ this.toString()); + this.toString());
@ -117,14 +114,8 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch {
try { try {
LdapUserDetailsImpl user = (LdapUserDetailsImpl) template.searchForSingleEntry( return template.searchForSingleEntry(searchBase, searchFilter, new String[] {username});
searchBase, searchFilter, new String[] {username}, userDetailsMapper);
if (!username.equals(user.getUsername())) {
logger.debug("Search returned user object with different username: " + user.getUsername());
}
return user;
} catch (IncorrectResultSizeDataAccessException notFound) { } catch (IncorrectResultSizeDataAccessException notFound) {
if (notFound.getActualSize() == 0) { if (notFound.getActualSize() == 0) {
throw new UsernameNotFoundException("User " + username + " not found in directory."); throw new UsernameNotFoundException("User " + username + " not found in directory.");
@ -163,10 +154,6 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch {
searchControls.setTimeLimit(searchTimeLimit); searchControls.setTimeLimit(searchTimeLimit);
} }
public void setUserDetailsMapper(LdapUserDetailsMapper userDetailsMapper) {
this.userDetailsMapper = userDetailsMapper;
}
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();

57
core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java

@ -19,14 +19,15 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.ldap.LdapDataAccessException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.ldap.authenticator.LdapShaPasswordEncoder;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider; import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.UserDetailsContextMapper;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -34,6 +35,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -123,6 +125,8 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
private LdapAuthenticator authenticator; private LdapAuthenticator authenticator;
private LdapAuthoritiesPopulator authoritiesPopulator; private LdapAuthoritiesPopulator authoritiesPopulator;
private UserDetailsContextMapper userDetailsContextMapper = new LdapUserDetailsMapper();
private PasswordEncoder passwordEncoder = new LdapShaPasswordEncoder();
private boolean includeDetailsObject = true; private boolean includeDetailsObject = true;
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
@ -149,7 +153,7 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
public LdapAuthenticationProvider(LdapAuthenticator authenticator) { public LdapAuthenticationProvider(LdapAuthenticator authenticator) {
this.setAuthenticator(authenticator); this.setAuthenticator(authenticator);
this.setAuthoritiesPopulator(new NullAuthoritiesPopulator()); this.setAuthoritiesPopulator(new NullAuthoritiesPopulator());
} }
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
@ -171,44 +175,23 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
return authoritiesPopulator; return authoritiesPopulator;
} }
public void setUserDetailsContextMapper(UserDetailsContextMapper userDetailsContextMapper) {
Assert.notNull(userDetailsContextMapper, "UserDetailsContextMapper must not be null");
this.userDetailsContextMapper = userDetailsContextMapper;
}
protected void additionalAuthenticationChecks(UserDetails userDetails, protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException { throws AuthenticationException {
if (!userDetails.getPassword().equals(authentication.getCredentials().toString())) { String presentedPassword = authentication.getCredentials() == null ? "" :
authentication.getCredentials().toString();
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, null)) {
throw new BadCredentialsException(messages.getMessage( throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
includeDetailsObject ? userDetails : null); includeDetailsObject ? userDetails : null);
} }
} }
/**
* Creates the final <tt>UserDetails</tt> object that will be returned by the provider once the user has
* been authenticated.<p>The <tt>LdapAuthoritiesPopulator</tt> will be used to create the granted
* authorites for the user.</p>
* <p>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 <tt>ldapUser</tt>
* object and set the values of the username and password.</p>
*
* @param ldapUser The intermediate LdapUserDetails instance returned by the authenticator.
* @param username the username submitted to the provider
* @param password the password submitted to the provider
*
* @return The UserDetails for the successfully authenticated user.
*/
protected UserDetails createUserDetails(LdapUserDetails ldapUser, String username, String password) {
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(ldapUser);
user.setUsername(username);
user.setPassword(password);
GrantedAuthority[] extraAuthorities = getAuthoritiesPopulator().getGrantedAuthorities(ldapUser);
for (int i = 0; i < extraAuthorities.length; i++) {
user.addAuthority(extraAuthorities[i]);
}
return user.createUserDetails();
}
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException { throws AuthenticationException {
if (!StringUtils.hasLength(username)) { if (!StringUtils.hasLength(username)) {
@ -230,9 +213,11 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
} }
try { try {
LdapUserDetails ldapUser = getAuthenticator().authenticate(username, password); DirContextOperations user = getAuthenticator().authenticate(username, password);
GrantedAuthority[] extraAuthorities = getAuthoritiesPopulator().getGrantedAuthorities(user, username);
return createUserDetails(ldapUser, username, password); return userDetailsContextMapper.mapUserFromContext(user, username, extraAuthorities);
} catch (DataAccessException ldapAccessFailure) { } catch (DataAccessException ldapAccessFailure) {
throw new AuthenticationServiceException(ldapAccessFailure.getMessage(), ldapAccessFailure); throw new AuthenticationServiceException(ldapAccessFailure.getMessage(), ldapAccessFailure);
@ -250,7 +235,7 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
//~ Inner Classes ================================================================================================== //~ Inner Classes ==================================================================================================
private static class NullAuthoritiesPopulator implements LdapAuthoritiesPopulator { private static class NullAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) throws LdapDataAccessException { public GrantedAuthority[] getGrantedAuthorities(DirContextOperations userDetails, String username) {
return new GrantedAuthority[0]; return new GrantedAuthority[0];
} }
} }

3
core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticator.java

@ -16,6 +16,7 @@
package org.acegisecurity.providers.ldap; package org.acegisecurity.providers.ldap;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -40,5 +41,5 @@ public interface LdapAuthenticator {
* *
* @return the details of the successfully authenticated user. * @return the details of the successfully authenticated user.
*/ */
LdapUserDetails authenticate(String username, String password); DirContextOperations authenticate(String username, String password);
} }

6
core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthoritiesPopulator.java

@ -20,6 +20,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.ldap.LdapDataAccessException; import org.acegisecurity.ldap.LdapDataAccessException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -38,12 +39,11 @@ public interface LdapAuthoritiesPopulator {
/** /**
* Get the list of authorities for the user. * Get the list of authorities for the user.
* *
* @param userDetails the user details object which was returned by the LDAP authenticator. * @param user the context object which was returned by the LDAP authenticator.
* *
* @return the granted authorities for the given user. * @return the granted authorities for the given user.
* *
* @throws LdapDataAccessException if there is a problem accessing the directory. * @throws LdapDataAccessException if there is a problem accessing the directory.
*/ */
GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) GrantedAuthority[] getGrantedAuthorities(DirContextOperations user, String username) throws LdapDataAccessException;
throws LdapDataAccessException;
} }

13
core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java

@ -22,8 +22,6 @@ import org.acegisecurity.ldap.LdapUserSearch;
import org.acegisecurity.providers.ldap.LdapAuthenticator; import org.acegisecurity.providers.ldap.LdapAuthenticator;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
@ -31,7 +29,6 @@ import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor; import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.core.ContextMapper;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -49,7 +46,6 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, In
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
private InitialDirContextFactory initialDirContextFactory; private InitialDirContextFactory initialDirContextFactory;
private LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper();
/** Optional search object which can be used to locate a user when a simple DN match isn't sufficient */ /** Optional search object which can be used to locate a user when a simple DN match isn't sufficient */
private LdapUserSearch userSearch; private LdapUserSearch userSearch;
@ -110,10 +106,6 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, In
return userAttributes; return userAttributes;
} }
protected ContextMapper getUserDetailsMapper() {
return userDetailsMapper;
}
/** /**
* Builds list of possible DNs for the user, worked out from the <tt>userDnPatterns</tt> property. The * Builds list of possible DNs for the user, worked out from the <tt>userDnPatterns</tt> property. The
* returned value includes the root DN of the provider URL used to configure the * returned value includes the root DN of the provider URL used to configure the
@ -159,11 +151,6 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, In
this.userAttributes = userAttributes; this.userAttributes = userAttributes;
} }
public void setUserDetailsMapper(LdapUserDetailsMapper userDetailsMapper) {
Assert.notNull("userDetailsMapper must not be null");
this.userDetailsMapper = userDetailsMapper;
}
/** /**
* Sets the pattern which will be used to supply a DN for the user. The pattern should be the name relative * Sets the pattern which will be used to supply a DN for the user. The pattern should be the name relative
* to the root DN. The pattern argument {0} will contain the username. An example would be "cn={0},ou=people". * to the root DN. The pattern argument {0} will contain the username. An example would be "cn={0},ou=people".

21
core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java

@ -27,8 +27,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextOperations;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
import javax.naming.Name;
import java.util.Iterator; import java.util.Iterator;
@ -58,21 +60,21 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public LdapUserDetails authenticate(String username, String password) { public DirContextOperations authenticate(String username, String password) {
LdapUserDetails user = null; DirContextOperations user = null;
// If DN patterns are configured, try authenticating with them directly // If DN patterns are configured, try authenticating with them directly
Iterator dns = getUserDns(username).iterator(); Iterator dns = getUserDns(username).iterator();
while (dns.hasNext() && (user == null)) { while (dns.hasNext() && user == null) {
user = bindWithDn((String) dns.next(), username, password); user = bindWithDn((String) dns.next(), username, password);
} }
// Otherwise use the configured locator to find the user // Otherwise use the configured locator to find the user
// and authenticate with the returned DN. // and authenticate with the returned DN.
if ((user == null) && (getUserSearch() != null)) { if (user == null && getUserSearch() != null) {
LdapUserDetails userFromSearch = getUserSearch().searchForUser(username); DirContextOperations userFromSearch = getUserSearch().searchForUser(username);
user = bindWithDn(userFromSearch.getDn(), username, password); user = bindWithDn(userFromSearch.getDn().toString(), username, password);
} }
if (user == null) { if (user == null) {
@ -83,15 +85,13 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
return user; return user;
} }
private LdapUserDetails bindWithDn(String userDn, String username, String password) { private DirContextOperations bindWithDn(String userDn, String username, String password) {
SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate( SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(
new BindWithSpecificDnContextSource(getInitialDirContextFactory(), userDn, password)); new BindWithSpecificDnContextSource(getInitialDirContextFactory(), userDn, password));
try { try {
LdapUserDetailsImpl user = (LdapUserDetailsImpl) template.retrieveEntry(userDn, return template.retrieveEntry(userDn, getUserAttributes());
getUserDetailsMapper(), getUserAttributes());
return user;
} catch (BadCredentialsException e) { } catch (BadCredentialsException e) {
// This will be thrown if an invalid user name is used and the method may // This will be thrown if an invalid user name is used and the method may
// be called multiple times to try different names, so we trap the exception // be called multiple times to try different names, so we trap the exception
@ -117,7 +117,6 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
private String userDn; private String userDn;
private String password; private String password;
public BindWithSpecificDnContextSource(InitialDirContextFactory ctxFactory, String userDn, String password) { public BindWithSpecificDnContextSource(InitialDirContextFactory ctxFactory, String userDn, String password) {
this.ctxFactory = ctxFactory; this.ctxFactory = ctxFactory;
this.userDn = userDn; this.userDn = userDn;

7
core/src/main/java/org/acegisecurity/providers/ldap/authenticator/LdapShaPasswordEncoder.java

@ -32,6 +32,9 @@ import java.security.MessageDigest;
* base-64 encoded and have the label "{SHA}" (or "{SSHA}") prepended to the encoded hash. These can be made lower-case * base-64 encoded and have the label "{SHA}" (or "{SSHA}") prepended to the encoded hash. These can be made lower-case
* in the encoded password, if required, by setting the <tt>forceLowerCasePrefix</tt> property to true. * in the encoded password, if required, by setting the <tt>forceLowerCasePrefix</tt> property to true.
* *
* Also supports plain text passwords, so can safely be used in cases when both encoded and non-encoded passwords are in
* use or when a null implementation is required.
*
* @author Luke Taylor * @author Luke Taylor
* @version $Id$ * @version $Id$
*/ */
@ -129,6 +132,10 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
public boolean isPasswordValid(String encPass, String rawPass, Object salt) { public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
String encPassWithoutPrefix; String encPassWithoutPrefix;
if (!encPass.startsWith("{")) {
return encPass.equals(rawPass);
}
if (encPass.startsWith(SSHA_PREFIX) || encPass.startsWith(SSHA_PREFIX_LC)) { if (encPass.startsWith(SSHA_PREFIX) || encPass.startsWith(SSHA_PREFIX_LC)) {
encPassWithoutPrefix = encPass.substring(6); encPassWithoutPrefix = encPass.substring(6);
salt = extractSalt(encPass); salt = extractSalt(encPass);

30
core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java

@ -24,13 +24,12 @@ import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.providers.encoding.PasswordEncoder; import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.core.DirContextOperations;
import java.util.Iterator; import java.util.Iterator;
@ -70,20 +69,19 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public LdapUserDetails authenticate(final String username, final String password) { public DirContextOperations authenticate(final String username, final String password) {
// locate the user and check the password // locate the user and check the password
LdapUserDetails user = null; DirContextOperations user = null;
Iterator dns = getUserDns(username).iterator(); Iterator dns = getUserDns(username).iterator();
SpringSecurityLdapTemplate ldapTemplate = new SpringSecurityLdapTemplate(getInitialDirContextFactory()); SpringSecurityLdapTemplate ldapTemplate = new SpringSecurityLdapTemplate(getInitialDirContextFactory());
while (dns.hasNext() && (user == null)) { while (dns.hasNext() && user == null) {
final String userDn = (String) dns.next(); final String userDn = (String) dns.next();
if (ldapTemplate.nameExists(userDn)) { if (ldapTemplate.nameExists(userDn)) {
user = (LdapUserDetailsImpl) user = ldapTemplate.retrieveEntry(userDn, getUserAttributes());
ldapTemplate.retrieveEntry(userDn, getUserDetailsMapper(), getUserAttributes());
} }
} }
@ -95,7 +93,7 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
throw new UsernameNotFoundException(username); throw new UsernameNotFoundException(username);
} }
String retrievedPassword = user.getPassword(); Object retrievedPassword = user.getObjectAttribute(passwordAttributeName);
if (retrievedPassword != null) { if (retrievedPassword != null) {
if (!verifyPassword(password, retrievedPassword)) { if (!verifyPassword(password, retrievedPassword)) {
@ -107,15 +105,14 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Password attribute wasn't retrieved for user '" + username + "' using mapper " logger.debug("Password attribute wasn't retrieved for user '" + username
+ getUserDetailsMapper() + ". Performing LDAP compare of password attribute '" + passwordAttributeName + "'. Performing LDAP compare of password attribute '" + passwordAttributeName + "'");
+ "'");
} }
String encodedPassword = passwordEncoder.encodePassword(password, null); String encodedPassword = passwordEncoder.encodePassword(password, null);
byte[] passwordBytes = LdapUtils.getUtf8Bytes(encodedPassword); byte[] passwordBytes = LdapUtils.getUtf8Bytes(encodedPassword);
if (!ldapTemplate.compare(user.getDn(), passwordAttributeName, passwordBytes)) { if (!ldapTemplate.compare(user.getDn().toString(), passwordAttributeName, passwordBytes)) {
throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials", throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials",
"Bad credentials")); "Bad credentials"));
} }
@ -141,12 +138,17 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
* *
* @return true if they match * @return true if they match
*/ */
private boolean verifyPassword(String password, String ldapPassword) { protected boolean verifyPassword(String password, Object ldapPassword) {
if (!(ldapPassword instanceof String)) {
// Assume it's binary
ldapPassword = new String((byte[]) ldapPassword);
}
if (ldapPassword.equals(password)) { if (ldapPassword.equals(password)) {
return true; return true;
} }
if (passwordEncoder.isPasswordValid(ldapPassword, password, null)) { if (passwordEncoder.isPasswordValid((String)ldapPassword, password, null)) {
return true; return true;
} }

48
core/src/main/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java

@ -29,6 +29,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.core.DirContextOperations;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -156,11 +157,11 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
* roles for the given user (on top of those obtained from the standard * roles for the given user (on top of those obtained from the standard
* search implemented by this class). * search implemented by this class).
* *
* @param ldapUser the user who's roles are required * @param user the context representing the user who's roles are required
* @return the extra roles which will be merged with those returned by the group search * @return the extra roles which will be merged with those returned by the group search
*/ */
protected Set getAdditionalRoles(LdapUserDetails ldapUser) { protected Set getAdditionalRoles(DirContextOperations user, String username) {
return null; return null;
} }
@ -168,26 +169,19 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
* Obtains the authorities for the user who's directory entry is represented by * Obtains the authorities for the user who's directory entry is represented by
* the supplied LdapUserDetails object. * the supplied LdapUserDetails object.
* *
* @param userDetails the user who's authorities are required * @param user the user who's authorities are required
* @return the set of roles granted to the user. * @return the set of roles granted to the user.
*/ */
public final GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) { public final GrantedAuthority[] getGrantedAuthorities(DirContextOperations user, String username) {
String userDn = userDetails.getDn(); String userDn = user.getDn().toString();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Getting authorities for user " + userDn); logger.debug("Getting authorities for user " + userDn);
} }
Set roles = getGroupMembershipRoles(userDn, userDetails.getUsername()); Set roles = getGroupMembershipRoles(userDn, username);
// Temporary use of deprecated method Set extraRoles = getAdditionalRoles(user, username);
Set oldGroupRoles = getGroupMembershipRoles(userDn, userDetails.getAttributes());
if (oldGroupRoles != null) {
roles.addAll(oldGroupRoles);
}
Set extraRoles = getAdditionalRoles(userDetails);
if (extraRoles != null) { if (extraRoles != null) {
roles.addAll(extraRoles); roles.addAll(extraRoles);
@ -200,19 +194,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
return (GrantedAuthority[]) roles.toArray(new GrantedAuthority[roles.size()]); return (GrantedAuthority[]) roles.toArray(new GrantedAuthority[roles.size()]);
} }
// protected Set getRolesFromUserAttributes(String userDn, Attributes userAttributes) {
// Set userRoles = new HashSet();
//
// for(int i=0; userRoleAttributes != null && i < userRoleAttributes.length; i++) {
// Attribute roleAttribute = userAttributes.get(userRoleAttributes[i]);
//
// addAttributeValuesToRoleSet(roleAttribute, userRoles);
// }
//
// return userRoles;
// }
public Set getGroupMembershipRoles(String userDn, String username) { public Set getGroupMembershipRoles(String userDn, String username) {
Set authorities = new HashSet(); Set authorities = new HashSet();
@ -247,19 +228,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
return authorities; return authorities;
} }
/**
* Searches for groups the user is a member of.
*
* @param userDn the user's distinguished name.
* @param userAttributes the retrieved user's attributes (unused by default).
* @return the set of roles obtained from a group membership search, or null if <tt>groupSearchBase</tt> has been
* set.
* @deprecated Subclasses should implement <tt>getAdditionalRoles</tt> instead.
*/
protected Set getGroupMembershipRoles(String userDn, Attributes userAttributes) {
return new HashSet();
}
protected InitialDirContextFactory getInitialDirContextFactory() { protected InitialDirContextFactory getInitialDirContextFactory() {
return initialDirContextFactory; return initialDirContextFactory;
} }

71
core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java

@ -17,6 +17,7 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -25,6 +26,7 @@ import org.springframework.util.Assert;
import org.springframework.ldap.UncategorizedLdapException; import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.core.ContextMapper; import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.directory.Attribute; import javax.naming.directory.Attribute;
@ -36,11 +38,10 @@ import javax.naming.directory.Attribute;
* @author Luke Taylor * @author Luke Taylor
* @version $Id$ * @version $Id$
*/ */
public class LdapUserDetailsMapper implements ContextMapper { public class LdapUserDetailsMapper implements UserDetailsContextMapper {
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
private final Log logger = LogFactory.getLog(LdapUserDetailsMapper.class); private final Log logger = LogFactory.getLog(LdapUserDetailsMapper.class);
private String usernameAttributeName = "uid";
private String passwordAttributeName = "userPassword"; private String passwordAttributeName = "userPassword";
private String rolePrefix = "ROLE_"; private String rolePrefix = "ROLE_";
private String[] roleAttributes = null; private String[] roleAttributes = null;
@ -48,25 +49,21 @@ public class LdapUserDetailsMapper implements ContextMapper {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public Object mapFromContext(Object ctxObj) { public UserDetails mapUserFromContext(DirContextOperations ctx, String username, GrantedAuthority[] authorities) {
Assert.isInstanceOf(DirContextAdapter.class, ctxObj, "Can only map from DirContextAdapter instances");
DirContextAdapter ctx = (DirContextAdapter)ctxObj;
String dn = ctx.getNameInNamespace(); String dn = ctx.getNameInNamespace();
logger.debug("Mapping user details from context with DN: " + dn); logger.debug("Mapping user details from context with DN: " + dn);
LdapUserDetailsImpl.Essence essence = new LdapUserDetailsImpl.Essence(); LdapUserDetailsImpl.Essence essence = new LdapUserDetailsImpl.Essence();
essence.setDn(dn); essence.setDn(dn);
essence.setAttributes(ctx.getAttributes());
Attribute passwordAttribute = ctx.getAttributes().get(passwordAttributeName); Object passwordValue = ctx.getObjectAttribute(passwordAttributeName);
if (passwordAttribute != null) { if (passwordValue != null) {
essence.setPassword(mapPassword(passwordAttribute)); essence.setPassword(mapPassword(passwordValue));
} }
essence.setUsername(mapUsername(ctx)); essence.setUsername(username);
// Map the roles // Map the roles
for (int i = 0; (roleAttributes != null) && (i < roleAttributes.length); i++) { for (int i = 0; (roleAttributes != null) && (i < roleAttributes.length); i++) {
@ -86,53 +83,38 @@ public class LdapUserDetailsMapper implements ContextMapper {
} }
} }
// Add the supplied authorities
for (int i=0; i < authorities.length; i++) {
essence.addAuthority(authorities[i]);
}
return essence.createUserDetails(); return essence.createUserDetails();
//return essence;
}
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
} }
/** /**
* Extension point to allow customized creation of the user's password from * Extension point to allow customized creation of the user's password from
* the attribute stored in the directory. * the attribute stored in the directory.
* *
* @param passwordAttribute the attribute instance containing the password * @param passwordValue the value of the password attribute
* @return a String representation of the password. * @return a String representation of the password.
*/ */
protected String mapPassword(Attribute passwordAttribute) { protected String mapPassword(Object passwordValue) {
Object retrievedPassword = null;
try {
retrievedPassword = passwordAttribute.get();
} catch (NamingException e) {
throw new UncategorizedLdapException("Failed to get password attribute", e);
}
if (!(retrievedPassword instanceof String)) { if (!(passwordValue instanceof String)) {
// Assume it's binary // Assume it's binary
retrievedPassword = new String((byte[]) retrievedPassword); passwordValue = new String((byte[]) passwordValue);
} }
return (String) retrievedPassword; return (String) passwordValue;
} }
protected String mapUsername(DirContextAdapter ctx) {
Attribute usernameAttribute = ctx.getAttributes().get(usernameAttributeName);
String username;
if (usernameAttribute == null) {
throw new UncategorizedLdapException(
"Failed to get attribute " + usernameAttributeName + " from context");
}
try {
username = (String) usernameAttribute.get();
} catch (NamingException e) {
throw new UncategorizedLdapException("Failed to get username from attribute " + usernameAttributeName, e);
}
return username;
}
/** /**
* Creates a GrantedAuthority from a role attribute. Override to customize * Creates a GrantedAuthority from a role attribute. Override to customize
* authority object creation. * authority object creation.
@ -175,11 +157,6 @@ public class LdapUserDetailsMapper implements ContextMapper {
this.passwordAttributeName = passwordAttributeName; this.passwordAttributeName = passwordAttributeName;
} }
public void setUsernameAttributeName(String usernameAttributeName) {
this.usernameAttributeName = usernameAttributeName;
}
/** /**
* The names of any attributes in the user's entry which represent application * The names of any attributes in the user's entry which represent application
* roles. These will be converted to <tt>GrantedAuthority</tt>s and added to the * roles. These will be converted to <tt>GrantedAuthority</tt>s and added to the

14
core/src/test/java/org/acegisecurity/ldap/search/FilterBasedLdapUserSearchTests.java

@ -22,6 +22,7 @@ import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -48,8 +49,8 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
locator.setSearchTimeLimit(0); locator.setSearchTimeLimit(0);
locator.setDerefLinkFlag(false); locator.setDerefLinkFlag(false);
LdapUserDetails bob = locator.searchForUser("bob"); DirContextOperations bob = locator.searchForUser("bob");
assertEquals("bob", bob.getUsername()); assertEquals("bob", bob.getStringAttribute("uid"));
// name is wrong with embedded apacheDS // name is wrong with embedded apacheDS
// assertEquals("uid=bob,ou=people,dc=acegisecurity,dc=org", bob.getDn()); // assertEquals("uid=bob,ou=people,dc=acegisecurity,dc=org", bob.getDn());
@ -61,9 +62,8 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
"(&(cn=*)(!(|(uid={0})(uid=marissa))))", dirCtxFactory); "(&(cn=*)(!(|(uid={0})(uid=marissa))))", dirCtxFactory);
// Search for bob, get back ben... // Search for bob, get back ben...
LdapUserDetails ben = locator.searchForUser("bob"); DirContextOperations ben = locator.searchForUser("bob");
String cn = (String) ben.getAttributes().get("cn").get(); assertEquals("Ben Alex", ben.getStringAttribute("cn"));
assertEquals("Ben Alex", cn);
// assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn()); // assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn());
} }
@ -91,8 +91,8 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory); FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory);
locator.setSearchSubtree(true); locator.setSearchSubtree(true);
LdapUserDetails ben = locator.searchForUser("Ben Alex"); DirContextOperations ben = locator.searchForUser("Ben Alex");
assertEquals("ben", ben.getUsername()); assertEquals("ben", ben.getStringAttribute("uid"));
// assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn()); // assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn());
} }

52
core/src/test/java/org/acegisecurity/providers/ldap/LdapAuthenticationProviderTests.java

@ -24,8 +24,11 @@ import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import java.util.ArrayList; import java.util.ArrayList;
@ -54,14 +57,14 @@ public class LdapAuthenticationProviderTests extends TestCase {
public void testDifferentCacheValueCausesException() { public void testDifferentCacheValueCausesException() {
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
new MockAuthoritiesPopulator()); new MockAuthoritiesPopulator());
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
// User is authenticated here // User is authenticated here
UserDetails user = ldapProvider.retrieveUser("bob", authRequest); UserDetails user = ldapProvider.retrieveUser("ben", authRequest);
// Assume the user details object is cached... // Assume the user details object is cached...
// And a subsequent authentication request comes in on the cached data // And a subsequent authentication request comes in on the cached data
authRequest = new UsernamePasswordAuthenticationToken("bob", "wrongpassword"); authRequest = new UsernamePasswordAuthenticationToken("ben", "wrongpassword");
try { try {
ldapProvider.additionalAuthenticationChecks(user, authRequest); ldapProvider.additionalAuthenticationChecks(user, authRequest);
@ -95,14 +98,17 @@ public class LdapAuthenticationProviderTests extends TestCase {
public void testNormalUsage() { public void testNormalUsage() {
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(), LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
new MockAuthoritiesPopulator()); new MockAuthoritiesPopulator());
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
userMapper.setRoleAttributes(new String[] {"ou"});
ldapProvider.setUserDetailsContextMapper(userMapper);
assertNotNull(ldapProvider.getAuthoritiesPopulator()); assertNotNull(ldapProvider.getAuthoritiesPopulator());
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
UserDetails user = ldapProvider.retrieveUser("bob", authRequest); UserDetails user = ldapProvider.retrieveUser("ben", authRequest);
assertEquals(2, user.getAuthorities().length); assertEquals(2, user.getAuthorities().length);
assertEquals("bobspassword", user.getPassword()); assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", user.getPassword());
assertEquals("bob", user.getUsername()); assertEquals("ben", user.getUsername());
ArrayList authorities = new ArrayList(); ArrayList authorities = new ArrayList();
authorities.add(user.getAuthorities()[0].getAuthority()); authorities.add(user.getAuthorities()[0].getAuthority());
@ -116,8 +122,11 @@ public class LdapAuthenticationProviderTests extends TestCase {
public void testUseWithNullAuthoritiesPopulatorReturnsCorrectRole() { public void testUseWithNullAuthoritiesPopulatorReturnsCorrectRole() {
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator()); LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator());
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
UserDetails user = ldapProvider.retrieveUser("bob", authRequest); userMapper.setRoleAttributes(new String[] {"ou"});
ldapProvider.setUserDetailsContextMapper(userMapper);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
UserDetails user = ldapProvider.retrieveUser("ben", authRequest);
assertEquals(1, user.getAuthorities().length); assertEquals(1, user.getAuthorities().length);
assertEquals("ROLE_FROM_ENTRY", user.getAuthorities()[0].getAuthority()); assertEquals("ROLE_FROM_ENTRY", user.getAuthorities()[0].getAuthority());
} }
@ -125,23 +134,20 @@ public class LdapAuthenticationProviderTests extends TestCase {
//~ Inner Classes ================================================================================================== //~ Inner Classes ==================================================================================================
class MockAuthenticator implements LdapAuthenticator { class MockAuthenticator implements LdapAuthenticator {
Attributes userAttributes = new BasicAttributes("cn", "bob");
public LdapUserDetails authenticate(String username, String password) { public DirContextOperations authenticate(String username, String password) {
LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter();
userEssence.setPassword("{SHA}anencodedpassword"); ctx.setAttributeValue("ou", "FROM_ENTRY");
userEssence.setAttributes(userAttributes);
if (username.equals("bob") && password.equals("bobspassword")) { if (username.equals("ben") && password.equals("benspassword")) {
userEssence.setDn("cn=bob,ou=people,dc=acegisecurity,dc=org"); ctx.setDn(new DistinguishedName("cn=ben,ou=people,dc=acegisecurity,dc=org"));
userEssence.addAuthority(new GrantedAuthorityImpl("ROLE_FROM_ENTRY")); ctx.setAttributeValue("userPassword","{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=");
return userEssence.createUserDetails(); return ctx;
} else if (username.equals("jen") && password.equals("")) { } else if (username.equals("jen") && password.equals("")) {
userEssence.setDn("cn=jen,ou=people,dc=acegisecurity,dc=org"); ctx.setDn(new DistinguishedName("cn=jen,ou=people,dc=acegisecurity,dc=org"));
userEssence.addAuthority(new GrantedAuthorityImpl("ROLE_FROM_ENTRY"));
return userEssence.createUserDetails(); return ctx;
} }
throw new BadCredentialsException("Authentication failed."); throw new BadCredentialsException("Authentication failed.");
@ -169,7 +175,7 @@ public class LdapAuthenticationProviderTests extends TestCase {
// assertEquals(2, auth.getAuthorities().length); // assertEquals(2, auth.getAuthorities().length);
// } // }
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator { class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetailsll) { public GrantedAuthority[] getGrantedAuthorities(DirContextOperations userCtx, String username) {
return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR")}; return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR")};
} }
} }

31
core/src/test/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticatorTests.java

@ -17,14 +17,13 @@ package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.AcegiMessageSource; import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.ldap.AbstractLdapIntegrationTests; import org.acegisecurity.ldap.AbstractLdapIntegrationTests;
import org.acegisecurity.ldap.InitialDirContextFactory; import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.springframework.ldap.core.DirContextAdapter;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.springframework.ldap.core.DistinguishedName;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -48,8 +47,8 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
public void testAuthenticationWithCorrectPasswordSucceeds() { public void testAuthenticationWithCorrectPasswordSucceeds() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
LdapUserDetails user = authenticator.authenticate("bob", "bobspassword"); DirContextOperations user = authenticator.authenticate("bob", "bobspassword");
assertEquals("bob", user.getUsername()); assertEquals("bob", user.getStringAttribute("uid"));
} }
public void testAuthenticationWithInvalidUserNameFails() { public void testAuthenticationWithInvalidUserNameFails() {
@ -62,10 +61,9 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
} }
public void testAuthenticationWithUserSearch() throws Exception { public void testAuthenticationWithUserSearch() throws Exception {
LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=bob,ou=people,dc=acegisecurity,dc=org"));
userEssence.setDn("uid=bob,ou=people,dc=acegisecurity,dc=org");
authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails())); authenticator.setUserSearch(new MockUserSearch(ctx));
authenticator.afterPropertiesSet(); authenticator.afterPropertiesSet();
authenticator.authenticate("bob", "bobspassword"); authenticator.authenticate("bob", "bobspassword");
} }
@ -79,21 +77,6 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
} catch (BadCredentialsException expected) {} } catch (BadCredentialsException expected) {}
} }
// TODO: Create separate tests for base class
public void testRoleRetrieval() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
userMapper.setRoleAttributes(new String[] {"uid"});
authenticator.setUserDetailsMapper(userMapper);
LdapUserDetails user = authenticator.authenticate("bob", "bobspassword");
assertEquals(1, user.getAuthorities().length);
assertEquals(new GrantedAuthorityImpl("ROLE_BOB"), user.getAuthorities()[0]);
}
public void testUserDnPatternReturnsCorrectDn() { public void testUserDnPatternReturnsCorrectDn() {
authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"});
assertEquals("cn=Joe,ou=people," + ((InitialDirContextFactory)getContextSource()).getRootDn(), authenticator.getUserDns("Joe").get(0)); assertEquals("cn=Joe,ou=people," + ((InitialDirContextFactory)getContextSource()).getRootDn(), authenticator.getUserDns("Joe").get(0));

10
core/src/test/java/org/acegisecurity/providers/ldap/authenticator/MockUserSearch.java

@ -18,11 +18,11 @@ package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.ldap.LdapUserSearch; import org.acegisecurity.ldap.LdapUserSearch;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.springframework.ldap.core.DirContextOperations;
/** /**
* *
DOCUMENT ME!
* *
* @author Luke Taylor * @author Luke Taylor
* @version $Id$ * @version $Id$
@ -30,17 +30,17 @@ DOCUMENT ME!
public class MockUserSearch implements LdapUserSearch { public class MockUserSearch implements LdapUserSearch {
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
LdapUserDetails user; DirContextOperations user;
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
public MockUserSearch(LdapUserDetails user) { public MockUserSearch(DirContextOperations user) {
this.user = user; this.user = user;
} }
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public LdapUserDetails searchForUser(String username) { public DirContextOperations searchForUser(String username) {
return user; return user;
} }
} }

35
core/src/test/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java

@ -23,9 +23,9 @@ import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.providers.encoding.PlaintextPasswordEncoder; import org.acegisecurity.providers.encoding.PlaintextPasswordEncoder;
import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.springframework.ldap.core.DirContextAdapter;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.springframework.ldap.core.DistinguishedName;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper; import org.springframework.ldap.core.DirContextOperations;
/** /**
@ -52,14 +52,13 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
// com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
} }
public void testAllAttributesAreRetrivedByDefault() { public void testAllAttributesAreRetrievedByDefault() {
LdapUserDetails user = authenticator.authenticate("bob", "bobspassword"); DirContextAdapter user = (DirContextAdapter) authenticator.authenticate("bob", "bobspassword");
//System.out.println(user.getAttributes().toString()); //System.out.println(user.getAttributes().toString());
assertEquals("User should have 5 attributes", 5, user.getAttributes().size()); assertEquals("User should have 5 attributes", 5, user.getAttributes().size());
} }
public void testFailedSearchGivesUserNotFoundException() public void testFailedSearchGivesUserNotFoundException() throws Exception {
throws Exception {
authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource()); authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource());
assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty());
authenticator.setUserSearch(new MockUserSearch(null)); authenticator.setUserSearch(new MockUserSearch(null));
@ -95,10 +94,11 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
} }
public void testLocalPasswordComparisonSucceedsWithCorrectPassword() { public void testLocalPasswordComparisonSucceedsWithCorrectPassword() {
LdapUserDetails user = authenticator.authenticate("bob", "bobspassword"); DirContextOperations user = authenticator.authenticate("bob", "bobspassword");
// check username is retrieved. // check username is retrieved.
assertEquals("bob", user.getUsername()); assertEquals("bob", user.getStringAttribute("uid"));
assertEquals("bobspassword", user.getPassword()); String password = new String((byte[])user.getObjectAttribute("userPassword"));
assertEquals("bobspassword", password);
} }
public void testMultipleDnPatternsWorkOk() { public void testMultipleDnPatternsWorkOk() {
@ -110,7 +110,7 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
authenticator.setUserAttributes(new String[] {"uid", "userPassword"}); authenticator.setUserAttributes(new String[] {"uid", "userPassword"});
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); DirContextAdapter user = (DirContextAdapter) authenticator.authenticate("Bob", "bobspassword");
assertEquals("Should have retrieved 2 attribute (uid, userPassword)", 2, user.getAttributes().size()); assertEquals("Should have retrieved 2 attribute (uid, userPassword)", 2, user.getAttributes().size());
} }
@ -136,12 +136,8 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
} }
public void testUseOfDifferentPasswordAttribute() { public void testUseOfDifferentPasswordAttribute() {
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
mapper.setPasswordAttributeName("uid");
authenticator.setPasswordAttributeName("uid"); authenticator.setPasswordAttributeName("uid");
authenticator.setUserDetailsMapper(mapper); authenticator.authenticate("bob", "bob");
LdapUserDetails bob = authenticator.authenticate("bob", "bob");
} }
public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { public void testLdapCompareWithDifferentPasswordAttributeSucceeds() {
@ -155,11 +151,10 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource()); authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource());
assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty());
LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=Bob,ou=people,dc=acegisecurity,dc=org"));
userEssence.setDn("uid=Bob,ou=people,dc=acegisecurity,dc=org"); ctx.setAttributeValue("userPassword", "bobspassword");
userEssence.setPassword("bobspassword");
authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails())); authenticator.setUserSearch(new MockUserSearch(ctx));
authenticator.authenticate("ShouldntBeUsed", "bobspassword"); authenticator.authenticate("ShouldntBeUsed", "bobspassword");
} }
} }

60
core/src/test/java/org/acegisecurity/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java

@ -21,6 +21,8 @@ import org.acegisecurity.ldap.AbstractLdapIntegrationTests;
import org.acegisecurity.ldap.InitialDirContextFactory; import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl; import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -45,39 +47,13 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio
} }
// public void testUserAttributeMappingToRoles() {
// DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator();
// populator.setUserRoleAttributes(new String[] {"userRole", "otherUserRole"});
// populator.getUserRoleAttributes();
//
// Attributes userAttrs = new BasicAttributes();
// BasicAttribute attr = new BasicAttribute("userRole", "role1");
// attr.add("role2");
// userAttrs.put(attr);
// attr = new BasicAttribute("otherUserRole", "role3");
// attr.add("role2"); // duplicate
// userAttrs.put(attr);
//
// LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
// user.setDn("Ignored");
// user.setUsername("Ignored");
// user.setAttributes(userAttrs);
//
// GrantedAuthority[] authorities =
// populator.getGrantedAuthorities(user.createUserDetails());
// assertEquals("User should have three roles", 3, authorities.length);
// }
public void testDefaultRoleIsAssignedWhenSet() { public void testDefaultRoleIsAssignedWhenSet() {
populator.setDefaultRole("ROLE_USER"); populator.setDefaultRole("ROLE_USER");
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("cn=notfound"));
user.setDn("cn=notfound");
user.setUsername("notfound");
user.setAttributes(new BasicAttributes());
GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails()); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "notfound");
assertEquals(1, authorities.length); assertEquals(1, authorities.length);
assertEquals("ROLE_USER", authorities[0].getAuthority()); assertEquals("ROLE_USER", authorities[0].getAuthority());
} }
@ -90,12 +66,9 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio
populator.setConvertToUpperCase(true); populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(member={0})"); populator.setGroupSearchFilter("(member={0})");
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org"));
user.setUsername("ben");
user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org");
user.setAttributes(new BasicAttributes());
GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails()); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "ben");
assertEquals("Should have 2 roles", 2, authorities.length); assertEquals("Should have 2 roles", 2, authorities.length);
@ -111,11 +84,10 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio
populator.setConvertToUpperCase(true); populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(ou={1})"); populator.setGroupSearchFilter("(ou={1})");
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org"));
user.setUsername("manager");
user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org"); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager");
GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails());
assertEquals("Should have 1 role", 1, authorities.length); assertEquals("Should have 1 role", 1, authorities.length);
assertEquals("ROLE_MANAGER", authorities[0].getAuthority()); assertEquals("ROLE_MANAGER", authorities[0].getAuthority());
} }
@ -124,11 +96,10 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio
populator.setGroupRoleAttribute("ou"); populator.setGroupRoleAttribute("ou");
populator.setConvertToUpperCase(true); populator.setConvertToUpperCase(true);
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org"));
user.setUsername("manager");
user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org"); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager");
GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails());
assertEquals("Should have 2 roles", 2, authorities.length); assertEquals("Should have 2 roles", 2, authorities.length);
Set roles = new HashSet(2); Set roles = new HashSet(2);
roles.add(authorities[0].getAuthority()); roles.add(authorities[0].getAuthority());
@ -142,11 +113,10 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio
populator.setConvertToUpperCase(true); populator.setConvertToUpperCase(true);
populator.setSearchSubtree(true); populator.setSearchSubtree(true);
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence(); DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org"));
user.setUsername("manager");
user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org"); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager");
GrantedAuthority[] authorities = populator.getGrantedAuthorities(user.createUserDetails());
assertEquals("Should have 3 roles", 3, authorities.length); assertEquals("Should have 3 roles", 3, authorities.length);
Set roles = new HashSet(3); Set roles = new HashSet(3);
roles.add(authorities[0].getAuthority()); roles.add(authorities[0].getAuthority());

7
core/src/test/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapperTests.java

@ -22,6 +22,7 @@ import javax.naming.directory.BasicAttribute;
import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.DistinguishedName;
import org.acegisecurity.GrantedAuthority;
/** /**
* Tests {@link LdapUserDetailsMapper}. * Tests {@link LdapUserDetailsMapper}.
@ -44,7 +45,7 @@ public class LdapUserDetailsMapperTests extends TestCase {
ctx.setAttributeValues("userRole", new String[] {"X", "Y", "Z"}); ctx.setAttributeValues("userRole", new String[] {"X", "Y", "Z"});
ctx.setAttributeValue("uid", "ani"); ctx.setAttributeValue("uid", "ani");
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx); LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", new GrantedAuthority[0]);
assertEquals(3, user.getAuthorities().length); assertEquals(3, user.getAuthorities().length);
} }
@ -63,7 +64,7 @@ public class LdapUserDetailsMapperTests extends TestCase {
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName")); DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
ctx.setAttributeValue("uid", "ani"); ctx.setAttributeValue("uid", "ani");
LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx); LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", new GrantedAuthority[0]);
assertEquals(1, user.getAuthorities().length); assertEquals(1, user.getAuthorities().length);
assertEquals("ROLE_X", user.getAuthorities()[0].getAuthority()); assertEquals("ROLE_X", user.getAuthorities()[0].getAuthority());
@ -94,7 +95,7 @@ public class LdapUserDetailsMapperTests extends TestCase {
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName")); DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
ctx.setAttributeValue("uid", "ani"); ctx.setAttributeValue("uid", "ani");
LdapUserDetails user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx); LdapUserDetails user = (LdapUserDetailsImpl) mapper.mapUserFromContext(ctx, "ani", new GrantedAuthority[0]);
assertEquals("mypassword", user.getPassword()); assertEquals("mypassword", user.getPassword());
} }

Loading…
Cancel
Save