Added property to LdapAuthenticationProvider to allow the credentials to be set either using the submitted password (the default) or the credentials from the loaded UserDetails object (which may be null if the attribute isn't readable).

This commit is contained in:
Luke Taylor 2007-12-09 23:46:28 +00:00
parent 78529f6d28
commit 5382627d4a
2 changed files with 29 additions and 22 deletions

View File

@ -130,6 +130,7 @@ public class LdapAuthenticationProvider implements AuthenticationProvider {
private LdapAuthenticator authenticator;
private LdapAuthoritiesPopulator authoritiesPopulator;
private UserDetailsContextMapper userDetailsContextMapper = new LdapUserDetailsMapper();
private boolean useAuthenticationRequestCredentials = true;
//~ Constructors ===================================================================================================
@ -186,6 +187,18 @@ public class LdapAuthenticationProvider implements AuthenticationProvider {
return userDetailsContextMapper;
}
/**
* Determines whether the supplied password will be used as the credentials in the successful authentication
* token. If set to false, then the password will be obtained from the UserDetails object
* created by the configured mapper. Often it will not be possible to read the password from the directory, so
* defaults to true.
*
* @param useAuthenticationRequestCredentials
*/
public void setUseAuthenticationRequestCredentials(boolean useAuthenticationRequestCredentials) {
this.useAuthenticationRequestCredentials = useAuthenticationRequestCredentials;
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports",
@ -225,8 +238,9 @@ public class LdapAuthenticationProvider implements AuthenticationProvider {
protected Authentication createSuccessfulAuthentication(UsernamePasswordAuthenticationToken authentication,
UserDetails user) {
Object password = useAuthenticationRequestCredentials ? authentication.getCredentials() : user.getPassword();
return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
return new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
}
public boolean supports(Class authentication) {

View File

@ -98,7 +98,9 @@ public class LdapAuthenticationProviderTests extends TestCase {
assertNotNull(ldapProvider.getAuthoritiesPopulator());
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
UserDetails user = (UserDetails) ldapProvider.authenticate(authRequest).getPrincipal();
Authentication authResult = ldapProvider.authenticate(authRequest);
assertEquals("benspassword", authResult.getCredentials());
UserDetails user = (UserDetails) authResult.getPrincipal();
assertEquals(2, user.getAuthorities().length);
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", user.getPassword());
assertEquals("ben", user.getUsername());
@ -111,6 +113,17 @@ public class LdapAuthenticationProviderTests extends TestCase {
assertTrue(authorities.contains("ROLE_FROM_POPULATOR"));
}
public void testPasswordIsSetFromUserDataIfUseAuthenticationRequestCredentialsIsFalse() {
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
new MockAuthoritiesPopulator());
ldapProvider.setUseAuthenticationRequestCredentials(false);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("ben", "benspassword");
Authentication authResult = ldapProvider.authenticate(authRequest);
assertEquals("{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=", authResult.getCredentials());
}
public void testUseWithNullAuthoritiesPopulatorReturnsCorrectRole() {
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator());
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
@ -148,26 +161,6 @@ public class LdapAuthenticationProviderTests extends TestCase {
}
}
// This test kills apacheDS in embedded mode because the search returns an invalid DN
// public void testIntegration() throws Exception {
// BindAuthenticator authenticator = new BindAuthenticator(getInitialCtxFactory());
// //PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator();
// //authenticator.setUserDnPatterns("cn={0},ou=people");
//
// FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch("ou=people", "(cn={0})", getInitialCtxFactory());
//
// authenticator.setUserSearch(userSearch);
// authenticator.afterPropertiesSet();
//
// DefaultLdapAuthoritiesPopulator populator;
// populator = new DefaultLdapAuthoritiesPopulator(getInitialCtxFactory(), "ou=groups");
// populator.setRolePrefix("ROLE_");
//
// LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(authenticator, populator);
//
// Authentication auth = ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("Ben Alex","benspassword"));
// assertEquals(2, auth.getAuthorities().length);
// }
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public GrantedAuthority[] getGrantedAuthorities(DirContextOperations userCtx, String username) {
return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR")};