SEC-513: Ldap user manager implementation classes changed to use new spring ldap apis.

This commit is contained in:
Luke Taylor 2007-09-10 21:13:45 +00:00
parent 8177168d73
commit 6eb17c8546
11 changed files with 97 additions and 73 deletions

View File

@ -14,8 +14,9 @@
*/ */
package org.acegisecurity.userdetails.ldap; package org.acegisecurity.userdetails.ldap;
import org.springframework.ldap.support.DirContextOperations; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DirContextOperations;
/** /**
* UserDetails implementation whose properties are based on a subset of the * UserDetails implementation whose properties are based on a subset of the

View File

@ -16,8 +16,8 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.springframework.ldap.support.DirContextOperations; import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.util.Assert; import org.springframework.util.Assert;

View File

@ -18,8 +18,7 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.support.DirContextOperations; import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.support.DirContextAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;

View File

@ -21,23 +21,34 @@ import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextHolder;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.support.DistinguishedName; import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.LdapTemplate; import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.AttributesMapper; import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.ContextSource; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.ContextExecutor; import org.springframework.ldap.core.ContextExecutor;
import org.springframework.ldap.SearchExecutor; import org.springframework.ldap.core.SearchExecutor;
import org.springframework.ldap.EntryNotFoundException; import org.springframework.ldap.core.AttributesMapperCallbackHandler;
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 javax.naming.*;
import javax.naming.ldap.LdapContext; import javax.naming.ldap.LdapContext;
import javax.naming.directory.*; import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.SearchControls;
import java.util.*; import java.util.*;
/** /**
@ -150,9 +161,6 @@ public class LdapUserDetailsManager implements UserDetailsManager {
String username = authentication.getName(); String username = authentication.getName();
logger.debug("Changing password for user '"+ username); logger.debug("Changing password for user '"+ username);
final DistinguishedName dn = buildDn(username); final DistinguishedName dn = buildDn(username);
@ -172,7 +180,11 @@ 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);
ctx.reconnect(null); try {
ctx.reconnect(null);
} catch (javax.naming.AuthenticationException e) {
throw new BadCredentialsException("Authentication for password change failed.");
}
ctx.modifyAttributes(dn, passwordChange); ctx.modifyAttributes(dn, passwordChange);
@ -199,8 +211,8 @@ public class LdapUserDetailsManager implements UserDetailsManager {
} }
}; };
LdapTemplate.AttributesMapperCallbackHandler roleCollector = AttributesMapperCallbackHandler roleCollector =
template.new AttributesMapperCallbackHandler(roleMapper); new AttributesMapperCallbackHandler(roleMapper);
template.search(se, roleCollector); template.search(se, roleCollector);
List authorities = roleCollector.getList(); List authorities = roleCollector.getList();
@ -277,7 +289,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
LdapUtils.closeContext((Context) obj); LdapUtils.closeContext((Context) obj);
} }
return true; return true;
} catch(EntryNotFoundException e) { } catch(org.springframework.ldap.NameNotFoundException e) {
return false; return false;
} }
} }
@ -402,13 +414,14 @@ public class LdapUserDetailsManager implements UserDetailsManager {
/** /**
* This class allows us to set the <tt>updateMode</tt> property of DirContextAdapter when updating existing users. * This class allows us to set the <tt>updateMode</tt> property of DirContextAdapter when updating existing users.
* TODO: No longer needed as of Ldap 1.2.
*/ */
private static class UserContext extends DirContextAdapter { private static class UserContext extends DirContextAdapter {
public UserContext(Attributes pAttrs, Name dn) { public UserContext(Attributes pAttrs, Name dn) {
super(pAttrs, dn); super(pAttrs, dn);
} }
protected void setUpdateMode(boolean mode) { public void setUpdateMode(boolean mode) {
super.setUpdateMode(mode); super.setUpdateMode(mode);
} }
} }

View File

@ -18,21 +18,16 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.ldap.LdapEntryMapper;
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.ContextMapper;
import org.springframework.ldap.UncategorizedLdapException; import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.AttributesIntegrityViolationException; import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.directory.Attribute; import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
/** /**

View File

@ -14,9 +14,12 @@
*/ */
package org.acegisecurity.userdetails.ldap; package org.acegisecurity.userdetails.ldap;
import org.springframework.ldap.support.DirContextOperations;
import org.springframework.ldap.support.DirContextAdapter;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import org.acegisecurity.ldap.LdapUtils; import org.acegisecurity.ldap.LdapUtils;
import java.util.List; import java.util.List;

View File

@ -2,8 +2,8 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.springframework.ldap.support.DirContextOperations; import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**

View File

@ -16,8 +16,8 @@ package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.springframework.ldap.support.DirContextOperations; import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DirContextAdapter;
/** /**
* Operations to map a UserDetails object to and from a Spring LDAP <tt>DirContextOperations</tt> implementation. * Operations to map a UserDetails object to and from a Spring LDAP <tt>DirContextOperations</tt> implementation.

View File

@ -1,8 +1,9 @@
package org.acegisecurity.userdetails.ldap; package org.acegisecurity.userdetails.ldap;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.springframework.ldap.support.DirContextAdapter;
import org.springframework.ldap.support.DistinguishedName; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
/** /**
* @author Luke Taylor * @author Luke Taylor

View File

@ -14,36 +14,32 @@
*/ */
package org.acegisecurity.userdetails.ldap; package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.ldap.AbstractLdapServerTestCase; import org.acegisecurity.ldap.SpringSecurityLdapTemplate;
import org.acegisecurity.ldap.LdapUtils; import org.acegisecurity.ldap.AbstractLdapIntegrationTests;
import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UsernameNotFoundException; import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextHolder;
import org.springframework.ldap.LdapTemplate;
import org.springframework.ldap.support.DirContextAdapter;
import org.springframework.ldap.support.DistinguishedName;
import org.springframework.dao.DataAccessException;
import javax.naming.directory.DirContext; import org.springframework.ldap.core.DirContextAdapter;
import java.util.List;
import java.util.Iterator;
/** /**
* @author Luke Taylor * @author Luke Taylor
* @version $Id$ * @version $Id$
*/ */
public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase { public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
private static final GrantedAuthority[] TEST_AUTHORITIES = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_CLOWNS"), private static final GrantedAuthority[] TEST_AUTHORITIES = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_CLOWNS"),
new GrantedAuthorityImpl("ROLE_ACROBATS")}; new GrantedAuthorityImpl("ROLE_ACROBATS")};
private LdapUserDetailsManager mgr; private LdapUserDetailsManager mgr;
private LdapTemplate template; private SpringSecurityLdapTemplate template;
protected void onSetUp() { protected void onSetUp() throws Exception {
mgr = new LdapUserDetailsManager(getInitialCtxFactory()); super.onSetUp();
template = new LdapTemplate(getInitialCtxFactory()); mgr = new LdapUserDetailsManager(getContextSource());
template = new SpringSecurityLdapTemplate(getContextSource());
DirContextAdapter ctx = new DirContextAdapter(); DirContextAdapter ctx = new DirContextAdapter();
ctx.setAttributeValue("objectclass", "organizationalUnit"); ctx.setAttributeValue("objectclass", "organizationalUnit");
@ -57,10 +53,11 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
group.setAttributeValue("objectclass", "groupOfNames"); group.setAttributeValue("objectclass", "groupOfNames");
group.setAttributeValue("cn", "clowns"); group.setAttributeValue("cn", "clowns");
template.bind("cn=clowns,ou=testgroups", ctx, null); group.setAttributeValue("member", "cn=nobody,ou=testpeople,dc=acegisecurity,dc=org");
template.bind("cn=clowns,ou=testgroups", group, null);
group.setAttributeValue("cn", "acrobats"); group.setAttributeValue("cn", "acrobats");
template.bind("cn=acrobats,ou=testgroups", ctx, null); template.bind("cn=acrobats,ou=testgroups", group, null);
mgr.setUserDnBase("ou=testpeople"); mgr.setUserDnBase("ou=testpeople");
mgr.setGroupSearchBase("ou=testgroups"); mgr.setGroupSearchBase("ou=testgroups");
@ -70,21 +67,20 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
} }
protected void tearDown() throws Exception { protected void onTearDown() throws Exception {
Iterator people = template.list("ou=testpeople").iterator(); // Iterator people = template.list("ou=testpeople").iterator();
DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn())); // DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn()));
//
// while(people.hasNext()) {
// template.unbind((String) people.next() + ",ou=testpeople");
// }
while(people.hasNext()) { template.unbind("ou=testpeople",true);
template.unbind(LdapUtils.getRelativeName((String) people.next(), rootCtx)); template.unbind("ou=testgroups",true);
}
template.unbind("ou=testpeople");
template.unbind("cn=acrobats,ou=testgroups");
template.unbind("cn=clowns,ou=testgroups");
template.unbind("ou=testgroups");
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
super.onTearDown();
} }
public void testLoadUserByUsernameReturnsCorrectData() { public void testLoadUserByUsernameReturnsCorrectData() {
@ -154,26 +150,43 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
assertEquals(0, mgr.getUserAuthorities(mgr.buildDn("don"), "don").length); assertEquals(0, mgr.getUserAuthorities(mgr.buildDn("don"), "don").length);
} }
public void testPasswordChangeSucceeds() { public void testPasswordChangeWithCorrectOldPasswordSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence(); InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setCn(new String[] {"John Yossarian"}); p.setCn(new String[] {"John Yossarian"});
p.setSn("Yossarian"); p.setSn("Yossarian");
p.setUid("john"); p.setUid("johnyossarian");
p.setPassword("yossarianspassword"); p.setPassword("yossarianspassword");
p.setAuthorities(TEST_AUTHORITIES); p.setAuthorities(TEST_AUTHORITIES);
mgr.createUser(p.createUserDetails()); mgr.createUser(p.createUserDetails());
SecurityContextHolder.getContext().setAuthentication( SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken("john", "yossarianspassword", TEST_AUTHORITIES)); new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES));
mgr.changePassword("yossarianspassword", "yossariansnewpassword"); mgr.changePassword("yossarianspassword", "yossariansnewpassword");
assertTrue(template.compare("uid=johnyossarian,ou=testpeople,dc=acegisecurity,dc=org",
"userPassword", "yossariansnewpassword"));
}
public void testPasswordChangeWithWrongOldPasswordFails() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setCn(new String[] {"John Yossarian"});
p.setSn("Yossarian");
p.setUid("johnyossarian");
p.setPassword("yossarianspassword");
p.setAuthorities(TEST_AUTHORITIES);
mgr.createUser(p.createUserDetails());
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES));
try {
mgr.changePassword("wrongpassword", "yossariansnewpassword");
fail("Expected BadCredentialsException");
} catch (BadCredentialsException expected) {
}
} }
} }

View File

@ -20,9 +20,8 @@ import junit.framework.TestCase;
import javax.naming.directory.BasicAttributes; import javax.naming.directory.BasicAttributes;
import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttribute;
import org.acegisecurity.GrantedAuthorityImpl; import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.support.DirContextAdapter; import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.DistinguishedName;
/** /**
* Tests {@link LdapUserDetailsMapper}. * Tests {@link LdapUserDetailsMapper}.