SEC-513: Minor work on LDAP UserDetailsManager implementation.

This commit is contained in:
Luke Taylor 2007-12-06 00:13:42 +00:00
parent e3432c2407
commit a1abcc39d2
3 changed files with 23 additions and 27 deletions

View File

@ -3,6 +3,11 @@ package org.springframework.security.ldap;
import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.DistinguishedName;
/** /**
* This implementation appends a name component to the <tt>userDnBase</tt> context using the
* <tt>usernameAttributeName</tt> property. So if the <tt>uid</tt> attribute is used to store the username, and the
* base DN is <tt>cn=users</tt> and we are creating a new user called "sam", then the DN will be
* <tt>uid=sam,cn=users</tt>.
*
* @author Luke Taylor * @author Luke Taylor
* @version $Id$ * @version $Id$
*/ */
@ -11,11 +16,6 @@ public class DefaultLdapUsernameToDnMapper implements LdapUsernameToDnMapper {
private String usernameAttribute; private String usernameAttribute;
/** /**
* This implementation appends a name component to the <tt>userDnBase</tt> context using the
* <tt>usernameAttributeName</tt> property. So if the <tt>uid</tt> attribute is used to store the username, and the
* base DN is <tt>cn=users</tt> and we are creating a new user called "sam", then the DN will be
* <tt>uid=sam,cn=users</tt>.
*
* @param userDnBase the base name of the DN * @param userDnBase the base name of the DN
* @param usernameAttribute the attribute to append for the username component. * @param usernameAttribute the attribute to append for the username component.
*/ */
@ -24,6 +24,9 @@ public class DefaultLdapUsernameToDnMapper implements LdapUsernameToDnMapper {
this.usernameAttribute = usernameAttribute; this.usernameAttribute = usernameAttribute;
} }
/**
* Assembles the Distinguished Name that should be used the given username.
*/
public DistinguishedName buildDn(String username) { public DistinguishedName buildDn(String username) {
DistinguishedName dn = new DistinguishedName(userDnBase); DistinguishedName dn = new DistinguishedName(userDnBase);

View File

@ -119,7 +119,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
} }
}; };
private String[] attributesToRetrieve = null; private String[] attributesToRetrieve;
public LdapUserDetailsManager(ContextSource contextSource) { public LdapUserDetailsManager(ContextSource contextSource) {
template = new LdapTemplate(contextSource); template = new LdapTemplate(contextSource);
@ -186,6 +186,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
ctx.removeFromEnvironment("com.sun.jndi.ldap.connect.pool"); ctx.removeFromEnvironment("com.sun.jndi.ldap.connect.pool");
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, LdapUtils.getFullDn(dn, ctx).toUrl()); ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, LdapUtils.getFullDn(dn, ctx).toUrl());
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, oldPassword); ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, oldPassword);
// TODO: reconnect doesn't appear to actually change the credentials
try { try {
ctx.reconnect(null); ctx.reconnect(null);
} catch (javax.naming.AuthenticationException e) { } catch (javax.naming.AuthenticationException e) {
@ -317,11 +318,11 @@ public class LdapUserDetailsManager implements UserDetailsManager {
userDetailsMapper.mapUserToContext(user, ctx); userDetailsMapper.mapUserToContext(user, ctx);
} }
private void addAuthorities(DistinguishedName userDn, GrantedAuthority[] authorities) { protected void addAuthorities(DistinguishedName userDn, GrantedAuthority[] authorities) {
modifyAuthorities(userDn, authorities, DirContext.ADD_ATTRIBUTE); modifyAuthorities(userDn, authorities, DirContext.ADD_ATTRIBUTE);
} }
private void removeAuthorities(DistinguishedName userDn, GrantedAuthority[] authorities) { protected void removeAuthorities(DistinguishedName userDn, GrantedAuthority[] authorities) {
modifyAuthorities(userDn, authorities, DirContext.REMOVE_ATTRIBUTE); modifyAuthorities(userDn, authorities, DirContext.REMOVE_ATTRIBUTE);
} }

View File

@ -22,7 +22,6 @@ import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper; import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
import org.springframework.security.ldap.SpringSecurityLdapTemplate; import org.springframework.security.ldap.SpringSecurityLdapTemplate;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException; import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
@ -90,23 +89,17 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
public void testLoadUserByUsernameReturnsCorrectData() { public void testLoadUserByUsernameReturnsCorrectData() {
mgr.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=people","uid")); mgr.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=people","uid"));
mgr.setGroupSearchBase("ou=groups"); mgr.setGroupSearchBase("ou=groups");
UserDetails bob = mgr.loadUserByUsername("bob"); LdapUserDetails bob = (LdapUserDetails) mgr.loadUserByUsername("bob");
assertEquals("bob", bob.getUsername()); assertEquals("bob", bob.getUsername());
// password isn't read assertEquals("uid=bob, ou=people, dc=springframework, dc=org", bob.getDn());
//assertEquals("bobspassword", bob.getPassword()); assertEquals("bobspassword", bob.getPassword());
assertEquals(1, bob.getAuthorities().length); assertEquals(1, bob.getAuthorities().length);
} }
@Test @Test(expected = UsernameNotFoundException.class)
public void testLoadingInvalidUsernameThrowsUsernameNotFoundException() { public void testLoadingInvalidUsernameThrowsUsernameNotFoundException() {
mgr.loadUserByUsername("jim");
try {
mgr.loadUserByUsername("jim");
fail("Expected UsernameNotFoundException for user 'jim'");
} catch(UsernameNotFoundException expected) {
// expected
}
} }
@Test @Test
@ -123,6 +116,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
@Test @Test
public void testCreateNewUserSucceeds() { public void testCreateNewUserSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence(); InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
p.setCn(new String[] {"Joe Smeth"}); p.setCn(new String[] {"Joe Smeth"});
p.setSn("Smeth"); p.setSn("Smeth");
p.setUid("joe"); p.setUid("joe");
@ -134,6 +128,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
@Test @Test
public void testDeleteUserSucceeds() { public void testDeleteUserSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence(); InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
p.setCn(new String[] {"Don Smeth"}); p.setCn(new String[] {"Don Smeth"});
p.setSn("Smeth"); p.setSn("Smeth");
p.setUid("don"); p.setUid("don");
@ -162,6 +157,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
@Test @Test
public void testPasswordChangeWithCorrectOldPasswordSucceeds() { public void testPasswordChangeWithCorrectOldPasswordSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence(); InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
p.setCn(new String[] {"John Yossarian"}); p.setCn(new String[] {"John Yossarian"});
p.setSn("Yossarian"); p.setSn("Yossarian");
p.setUid("johnyossarian"); p.setUid("johnyossarian");
@ -179,9 +175,10 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
"userPassword", "yossariansnewpassword")); "userPassword", "yossariansnewpassword"));
} }
@Test @Test(expected = BadCredentialsException.class)
public void testPasswordChangeWithWrongOldPasswordFails() { public void testPasswordChangeWithWrongOldPasswordFails() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence(); InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
p.setCn(new String[] {"John Yossarian"}); p.setCn(new String[] {"John Yossarian"});
p.setSn("Yossarian"); p.setSn("Yossarian");
p.setUid("johnyossarian"); p.setUid("johnyossarian");
@ -193,11 +190,6 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
SecurityContextHolder.getContext().setAuthentication( SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES)); new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES));
try { mgr.changePassword("wrongpassword", "yossariansnewpassword");
mgr.changePassword("wrongpassword", "yossariansnewpassword");
fail("Expected BadCredentialsException");
} catch (BadCredentialsException expected) {
}
} }
} }