SEC-449: Make LdapUserDetailsMapper a pure ContextMapper so it can be used with LdapTemplate.

This commit is contained in:
Luke Taylor 2007-09-13 20:42:50 +00:00
parent 6d8f92e1b8
commit d208cf3824
8 changed files with 62 additions and 58 deletions

View File

@ -117,15 +117,14 @@ public class FilterBasedLdapUserSearch implements LdapUserSearch {
try { try {
LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) template.searchForSingleEntry( LdapUserDetailsImpl user = (LdapUserDetailsImpl) template.searchForSingleEntry(
searchBase, searchFilter, new String[] {username}, userDetailsMapper); searchBase, searchFilter, new String[] {username}, userDetailsMapper);
user.setUsername(username); if (!username.equals(user.getUsername())) {
// if (!username.equals(user.getUsername())) { logger.debug("Search returned user object with different username: " + user.getUsername());
// logger.debug("Search returned user object with different username: " + user.getUsername()); }
// }
return user.createUserDetails(); 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.");
@ -164,6 +163,10 @@ 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();

View File

@ -88,11 +88,10 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
new BindWithSpecificDnContextSource(getInitialDirContextFactory(), userDn, password)); new BindWithSpecificDnContextSource(getInitialDirContextFactory(), userDn, password));
try { try {
LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) template.retrieveEntry(userDn, LdapUserDetailsImpl user = (LdapUserDetailsImpl) template.retrieveEntry(userDn,
getUserDetailsMapper(), getUserAttributes()); getUserDetailsMapper(), getUserAttributes());
user.setUsername(username);
return user.createUserDetails(); 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

View File

@ -82,14 +82,12 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
final String userDn = (String) dns.next(); final String userDn = (String) dns.next();
if (ldapTemplate.nameExists(userDn)) { if (ldapTemplate.nameExists(userDn)) {
LdapUserDetailsImpl.Essence userEssence = (LdapUserDetailsImpl.Essence) user = (LdapUserDetailsImpl)
ldapTemplate.retrieveEntry(userDn, getUserDetailsMapper(), getUserAttributes()); ldapTemplate.retrieveEntry(userDn, getUserDetailsMapper(), getUserAttributes());
userEssence.setUsername(username);
user = userEssence.createUserDetails();
} }
} }
if ((user == null) && (getUserSearch() != null)) { if (user == null && getUserSearch() != null) {
user = getUserSearch().searchForUser(username); user = getUserSearch().searchForUser(username);
} }

View File

@ -40,7 +40,7 @@ public class LdapUserDetailsMapper implements ContextMapper {
//~ 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 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;
@ -66,7 +66,7 @@ public class LdapUserDetailsMapper implements ContextMapper {
essence.setPassword(mapPassword(passwordAttribute)); essence.setPassword(mapPassword(passwordAttribute));
} }
// essence.setUsername(mapUsername(ctx)); essence.setUsername(mapUsername(ctx));
// 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,8 +86,8 @@ public class LdapUserDetailsMapper implements ContextMapper {
} }
} }
//return essence.createUserDetails(); return essence.createUserDetails();
return essence; //return essence;
} }
/** /**
@ -115,23 +115,23 @@ public class LdapUserDetailsMapper implements ContextMapper {
} }
// protected String mapUsername(DirContextAdapter ctx) { protected String mapUsername(DirContextAdapter ctx) {
// Attribute usernameAttribute = ctx.getAttributes().get(usernameAttributeName); Attribute usernameAttribute = ctx.getAttributes().get(usernameAttributeName);
// String username; String username;
//
// if (usernameAttribute == null) { if (usernameAttribute == null) {
// throw new AttributesIntegrityViolationException( throw new UncategorizedLdapException(
// "Failed to get attribute " + usernameAttributeName + " from context"); "Failed to get attribute " + usernameAttributeName + " from context");
// } }
//
// try { try {
// username = (String) usernameAttribute.get(); username = (String) usernameAttribute.get();
// } catch (NamingException e) { } catch (NamingException e) {
// throw new UncategorizedLdapException("Failed to get username from attribute " + usernameAttributeName, e); throw new UncategorizedLdapException("Failed to get username from attribute " + usernameAttributeName, e);
// } }
//
// return username; return username;
// } }
/** /**
* Creates a GrantedAuthority from a role attribute. Override to customize * Creates a GrantedAuthority from a role attribute. Override to customize
@ -176,9 +176,9 @@ public class LdapUserDetailsMapper implements ContextMapper {
} }
// public void setUsernameAttributeName(String usernameAttributeName) { public void setUsernameAttributeName(String usernameAttributeName) {
// this.usernameAttributeName = 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

View File

@ -92,7 +92,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
locator.setSearchSubtree(true); locator.setSearchSubtree(true);
LdapUserDetails ben = locator.searchForUser("Ben Alex"); LdapUserDetails ben = locator.searchForUser("Ben Alex");
assertEquals("Ben Alex", ben.getUsername()); assertEquals("ben", ben.getUsername());
// assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn()); // assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn());
} }

View File

@ -23,6 +23,7 @@ import org.jmock.MockObjectTestCase;
import javax.naming.directory.Attributes; import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes; import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
import javax.naming.directory.BasicAttribute;
/** /**
@ -33,9 +34,10 @@ import javax.naming.directory.DirContext;
public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase { public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public void testLdapCompareIsUsedWhenPasswordIsNotRetrieved() public void testLdapCompareIsUsedWhenPasswordIsNotRetrieved() throws Exception {
throws Exception {
Mock mockCtx = mock(DirContext.class); Mock mockCtx = mock(DirContext.class);
BasicAttributes attrs = new BasicAttributes();
attrs.put(new BasicAttribute("uid", "bob"));
PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(new MockInitialDirContextFactory( PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(new MockInitialDirContextFactory(
(DirContext) mockCtx.proxy(), "dc=acegisecurity,dc=org")); (DirContext) mockCtx.proxy(), "dc=acegisecurity,dc=org"));
@ -46,7 +48,7 @@ public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase
mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org"));
mockCtx.expects(once()).method("lookup").with(eq("cn=Bob, ou=people")).will(returnValue(true)); mockCtx.expects(once()).method("lookup").with(eq("cn=Bob, ou=people")).will(returnValue(true));
mockCtx.expects(once()).method("getAttributes").with(eq("cn=Bob, ou=people"), NULL) mockCtx.expects(once()).method("getAttributes").with(eq("cn=Bob, ou=people"), NULL)
.will(returnValue(new BasicAttributes())); .will(returnValue(attrs));
// Setup a single return value (i.e. success) // Setup a single return value (i.e. success)
Attributes searchResults = new BasicAttributes("", null); Attributes searchResults = new BasicAttributes("", null);

View File

@ -86,7 +86,7 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
public void testLdapPasswordCompareFailsWithWrongPassword() { public void testLdapPasswordCompareFailsWithWrongPassword() {
// Don't retrieve the password // Don't retrieve the password
authenticator.setUserAttributes(new String[] {"cn", "sn"}); authenticator.setUserAttributes(new String[] {"uid", "cn", "sn"});
try { try {
authenticator.authenticate("Bob", "wrongpassword"); authenticator.authenticate("Bob", "wrongpassword");
fail("Authentication should fail with wrong password."); fail("Authentication should fail with wrong password.");
@ -95,9 +95,9 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
} }
public void testLocalPasswordComparisonSucceedsWithCorrectPassword() { public void testLocalPasswordComparisonSucceedsWithCorrectPassword() {
LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); LdapUserDetails user = authenticator.authenticate("bob", "bobspassword");
// check username is retrieved. // check username is retrieved.
assertEquals("Bob", user.getUsername()); assertEquals("bob", user.getUsername());
assertEquals("bobspassword", user.getPassword()); assertEquals("bobspassword", user.getPassword());
} }
@ -107,16 +107,16 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
} }
public void testOnlySpecifiedAttributesAreRetrieved() throws Exception { public void testOnlySpecifiedAttributesAreRetrieved() throws Exception {
authenticator.setUserAttributes(new String[] {"userPassword"}); authenticator.setUserAttributes(new String[] {"uid", "userPassword"});
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword"); LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword");
assertEquals("Should have retrieved 1 attribute (userPassword)", 1, user.getAttributes().size()); assertEquals("Should have retrieved 2 attribute (uid, userPassword)", 2, user.getAttributes().size());
} }
public void testLdapCompareSucceedsWithCorrectPassword() { public void testLdapCompareSucceedsWithCorrectPassword() {
// Don't retrieve the password // Don't retrieve the password
authenticator.setUserAttributes(new String[] {"cn"}); authenticator.setUserAttributes(new String[] {"uid"});
// Bob has a plaintext password. // Bob has a plaintext password.
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
authenticator.authenticate("bob", "bobspassword"); authenticator.authenticate("bob", "bobspassword");
@ -124,7 +124,7 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
public void testLdapCompareSucceedsWithShaEncodedPassword() { public void testLdapCompareSucceedsWithShaEncodedPassword() {
// Don't retrieve the password // Don't retrieve the password
authenticator.setUserAttributes(new String[] {"cn"}); authenticator.setUserAttributes(new String[] {"uid"});
authenticator.authenticate("ben", "benspassword"); authenticator.authenticate("ben", "benspassword");
} }
@ -145,10 +145,10 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
} }
public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { public void testLdapCompareWithDifferentPasswordAttributeSucceeds() {
authenticator.setUserAttributes(new String[] {"cn"}); authenticator.setUserAttributes(new String[] {"uid"});
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
authenticator.setPasswordAttributeName("uid"); authenticator.setPasswordAttributeName("cn");
authenticator.authenticate("bob", "bob"); authenticator.authenticate("bob", "Bob Hamilton");
} }
public void testWithUserSearch() { public void testWithUserSearch() {

View File

@ -42,10 +42,11 @@ public class LdapUserDetailsMapperTests extends TestCase {
DirContextAdapter ctx = new DirContextAdapter(); DirContextAdapter ctx = new DirContextAdapter();
ctx.setAttributeValues("userRole", new String[] {"X", "Y", "Z"}); ctx.setAttributeValues("userRole", new String[] {"X", "Y", "Z"});
ctx.setAttributeValue("uid", "ani");
LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) mapper.mapFromContext(ctx); LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx);
assertEquals(3, user.getGrantedAuthorities().length); assertEquals(3, user.getAuthorities().length);
} }
/** /**
@ -60,11 +61,12 @@ public class LdapUserDetailsMapperTests extends TestCase {
attrs.put(new BasicAttribute("userRole", "x")); attrs.put(new BasicAttribute("userRole", "x"));
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName")); DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
ctx.setAttributeValue("uid", "ani");
LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) mapper.mapFromContext(ctx); LdapUserDetailsImpl user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx);
assertEquals(1, user.getGrantedAuthorities().length); assertEquals(1, user.getAuthorities().length);
assertEquals("ROLE_X", user.getGrantedAuthorities()[0].getAuthority()); assertEquals("ROLE_X", user.getAuthorities()[0].getAuthority());
} }
// public void testNonStringRoleAttributeIsIgnoredByDefault() throws Exception { // public void testNonStringRoleAttributeIsIgnoredByDefault() throws Exception {
@ -90,9 +92,9 @@ public class LdapUserDetailsMapperTests extends TestCase {
attrs.put(new BasicAttribute("myappsPassword", "mypassword".getBytes())); attrs.put(new BasicAttribute("myappsPassword", "mypassword".getBytes()));
DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName")); DirContextAdapter ctx = new DirContextAdapter(attrs, new DistinguishedName("cn=someName"));
ctx.setAttributeValue("uid", "ani");
LdapUserDetails user = LdapUserDetails user = (LdapUserDetailsImpl) mapper.mapFromContext(ctx);
((LdapUserDetailsImpl.Essence) mapper.mapFromContext(ctx)).createUserDetails();
assertEquals("mypassword", user.getPassword()); assertEquals("mypassword", user.getPassword());
} }