From 5382627d4a6066c61d8a48a53715bcaaf4bbf820 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sun, 9 Dec 2007 23:46:28 +0000 Subject: [PATCH] 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). --- .../ldap/LdapAuthenticationProvider.java | 16 ++++++++- .../ldap/LdapAuthenticationProviderTests.java | 35 ++++++++----------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java b/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java index c7f2fcc4f0..580b7e2a4a 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java +++ b/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java @@ -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) { diff --git a/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java index eed4182e5d..c4288ff50b 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java @@ -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")};