SEC-264: changes to LDAP services.

This commit is contained in:
Luke Taylor
2006-05-15 20:53:10 +00:00
parent db042046e9
commit 65fe641900
22 changed files with 441 additions and 387 deletions

View File

@@ -19,8 +19,6 @@ import junit.framework.TestCase;
import java.util.Hashtable;
import org.apache.directory.server.core.jndi.CoreContextFactory;
/**
* @author Luke Taylor
* @version $Id$
@@ -31,16 +29,16 @@ public abstract class AbstractLdapServerTestCase extends TestCase {
protected static final String MANAGER_PASSWORD = "acegisecurity";
// External server config
// private static final String PROVIDER_URL = "ldap://monkeymachine:389/"+ROOT_DN;
// private static final String CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
// private static final Hashtable EXTRA_ENV = new Hashtable();
private static final String PROVIDER_URL = "ldap://monkeymachine:389/"+ROOT_DN;
private static final String CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
private static final Hashtable EXTRA_ENV = new Hashtable();
// Embedded (non-networked) server config
private static final LdapTestServer SERVER = new LdapTestServer();
private static final String PROVIDER_URL = ROOT_DN;
private static final String CONTEXT_FACTORY = CoreContextFactory.class.getName();
private static final Hashtable EXTRA_ENV = SERVER.getConfiguration().toJndiEnvironment();
// private static final LdapTestServer SERVER = new LdapTestServer();
// private static final String PROVIDER_URL = ROOT_DN;
// private static final String CONTEXT_FACTORY = CoreContextFactory.class.getName();
// private static final Hashtable EXTRA_ENV = SERVER.getConfiguration().toJndiEnvironment();
protected AbstractLdapServerTestCase() {
}

View File

@@ -33,27 +33,27 @@ public class LdapTemplateTests extends AbstractLdapServerTestCase {
public void testCompareOfCorrectValueSucceeds() {
assertTrue(template.compare("uid=bob,ou=people", "uid", "bob"));
assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "bob"));
}
public void testCompareOfWrongValueFails() {
assertFalse(template.compare("uid=bob,ou=people", "uid", "wrongvalue"));
assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "wrongvalue"));
}
public void testCompareOfCorrectByteValueSucceeds() {
// Doesn't work with embedded server due to bugs in apacheds
// assertTrue(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("bobspassword")));
// assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("bobspassword")));
}
public void testCompareOfWrongByteValueFails() {
// Doesn't work with embedded server due to bugs in apacheds
// assertFalse(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue")));
// assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue")));
}
public void testSearchForSingleAttributeValues() {
String param = "uid=ben,ou=people," + getInitialCtxFactory().getRootDn();
String param = "uid=ben,ou=people,dc=acegisecurity,dc=org";
Set values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "ou");

View File

@@ -2,9 +2,9 @@ package org.acegisecurity.ldap.search;
import org.acegisecurity.ldap.AbstractLdapServerTestCase;
import org.acegisecurity.ldap.DefaultInitialDirContextFactory;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
/**
* Tests for FilterBasedLdapUserSearch.
@@ -32,7 +32,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase {
public void testBasicSearch() throws Exception {
FilterBasedLdapUserSearch locator =
new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory);
LdapUserInfo bob = locator.searchForUser("bob");
LdapUserDetails bob = locator.searchForUser("bob");
locator.setSearchSubtree(false);
locator.setSearchTimeLimit(0);
// name is wrong with embedded apacheDS
@@ -45,7 +45,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase {
new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory);
locator.setSearchSubtree(true);
LdapUserInfo ben = locator.searchForUser("Ben Alex");
LdapUserDetails ben = locator.searchForUser("Ben Alex");
// assertEquals("uid=ben,ou=people,"+ROOT_DN, bob.getDn());
}
@@ -67,7 +67,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase {
try {
locator.searchForUser("Ignored");
fail("Expected exception for multiple search matches.");
} catch (BadCredentialsException expected) {
} catch (IncorrectResultSizeDataAccessException expected) {
}
}
@@ -80,7 +80,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapServerTestCase {
dirCtxFactory);
// Search for bob, get back ben...
LdapUserInfo ben = locator.searchForUser("bob");
LdapUserDetails ben = locator.searchForUser("bob");
String cn = (String)ben.getAttributes().get("cn").get();
assertEquals("Ben Alex", cn);
// assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn());

View File

@@ -6,11 +6,12 @@ import javax.naming.directory.BasicAttributes;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.AbstractLdapServerTestCase;
import org.acegisecurity.ldap.*;
import org.acegisecurity.ldap.DefaultInitialDirContextFactory;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
/**
* @author Luke Taylor
@@ -82,18 +83,20 @@ public class LdapAuthenticationProviderTests extends AbstractLdapServerTestCase
*/
class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public GrantedAuthority[] getGrantedAuthorities(String userDn, String dn, Attributes userAttributes) {
return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_USER") };
public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetailsll) {
return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_USER") };
}
}
class MockAuthenticator implements LdapAuthenticator {
Attributes userAttributes = new BasicAttributes("cn","bob");
public LdapUserInfo authenticate(String username, String password) {
public LdapUserDetails authenticate(String username, String password) {
if(username.equals("bob") && password.equals("bobspassword")) {
return new LdapUserInfo("cn=bob,ou=people,dc=acegisecurity,dc=org", userAttributes);
LdapUserDetailsImpl.Essence creator = new LdapUserDetailsImpl.Essence();
creator.setDn("cn=bob,ou=people,dc=acegisecurity,dc=org");
creator.setAttributes(userAttributes);
return creator.createUserDetails();
}
throw new BadCredentialsException("Authentication of Bob failed.");
}

View File

@@ -1,8 +1,11 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.AbstractLdapServerTestCase;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
/**
* Tests for {@link BindAuthenticator}.
@@ -26,12 +29,10 @@ public class BindAuthenticatorTests extends AbstractLdapServerTestCase {
public void testAuthenticationWithCorrectPasswordSucceeds() throws Exception {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
LdapUserInfo user = authenticator.authenticate("bob","bobspassword");
LdapUserDetails user = authenticator.authenticate("bob","bobspassword");
}
public void testAuthenticationWithWrongPasswordFails() {
// BindAuthenticator authenticator = new BindAuthenticator(dirCtxFactory);
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
try {
@@ -42,25 +43,36 @@ public class BindAuthenticatorTests extends AbstractLdapServerTestCase {
}
public void testAuthenticationWithUserSearch() throws Exception {
LdapUserInfo user = new LdapUserInfo("uid=bob,ou=people," + getInitialCtxFactory().getRootDn(), null);
authenticator.setUserSearch(new MockUserSearch(user));
LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence();
userEssence.setDn("uid=bob,ou=people,dc=acegisecurity,dc=org");
authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails()));
authenticator.afterPropertiesSet();
authenticator.authenticate("bob","bobspassword");
}
public void testAuthenticationWithInvalidUserNameFails() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
// Apache DS falls apart with unknown DNs.
//
// public void testAuthenticationWithInvalidUserNameFails() {
// BindAuthenticator authenticator = new BindAuthenticator();
//
// authenticator.setInitialDirContextFactory(dirCtxFactory);
// authenticator.setUserDnPatterns("cn={0},ou=people");
// try {
// authenticator.authenticate("Baz","bobspassword");
// fail("Shouldn't be able to bind with invalid username");
// } catch(BadCredentialsException expected) {
// }
// }
try {
authenticator.authenticate("nonexistentsuser","bobspassword");
fail("Shouldn't be able to bind with invalid username");
} catch(BadCredentialsException expected) {
}
}
// TODO: Create separate tests for base class
public void testRoleRetrieval() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
LdapUserDetailsMapper userMapper = new LdapUserDetailsMapper();
userMapper.setRoleAttributes(new String[] {"uid"});
authenticator.setUserDetailsMapper(userMapper);
LdapUserDetails user = authenticator.authenticate("bob","bobspassword");
assertEquals(1, user.getAuthorities().length);
assertEquals(new GrantedAuthorityImpl("ROLE_BOB"), user.getAuthorities()[0]);
}
}

View File

@@ -1,20 +1,20 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.LdapUserSearch;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
/**
* @author Luke Taylor
* @version $Id$
*/
public class MockUserSearch implements LdapUserSearch {
LdapUserInfo user;
LdapUserDetails user;
public MockUserSearch(LdapUserInfo user) {
public MockUserSearch(LdapUserDetails user) {
this.user = user;
}
public LdapUserInfo searchForUser(String username) {
public LdapUserDetails searchForUser(String username) {
return user;
}
}

View File

@@ -27,12 +27,13 @@ public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase
// Get the mock to return an empty attribute set
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("getAttributes").with(eq("cn=Bob,ou=people"), NULL).will(returnValue(new BasicAttributes()));
// Setup a single return value (i.e. success)
Attributes searchResults = new BasicAttributes("", null);
mockCtx.expects(once()).method("search").with(eq("cn=Bob,ou=people"),
eq("(userPassword={0})"), NOT_NULL, NOT_NULL).will(returnValue(searchResults.getAll()));
mockCtx.expects(once()).method("close");
mockCtx.expects(atLeastOnce()).method("close");
authenticator.authenticate("Bob", "bobspassword");
}

View File

@@ -1,11 +1,11 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.AbstractLdapServerTestCase;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import javax.naming.directory.BasicAttributes;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
/**
* Tests for {@link PasswordComparisonAuthenticator}.
@@ -87,7 +87,7 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTest
}
public void testAllAttributesAreRetrivedByDefault() {
LdapUserInfo user = authenticator.authenticate("Bob", "bobspassword");
LdapUserDetails user = authenticator.authenticate("Bob", "bobspassword");
System.out.println(user.getAttributes().toString());
assertEquals("User should have 5 attributes", 5, user.getAttributes().size());
@@ -103,7 +103,10 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTest
}
*/
public void testUseOfDifferentPasswordAttribute() {
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
mapper.setPasswordAttributeName("uid");
authenticator.setPasswordAttributeName("uid");
authenticator.setUserDetailsMapper(mapper);
authenticator.authenticate("bob", "bob");
}
/*
@@ -119,10 +122,11 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapServerTest
authenticator = new PasswordComparisonAuthenticator(getInitialCtxFactory());
assertTrue("User DN matches shouldn't be available",
authenticator.getUserDns("Bob").isEmpty());
LdapUserInfo user = new LdapUserInfo("uid=Bob,ou=people" +
getInitialCtxFactory().getRootDn(),
new BasicAttributes("userPassword","bobspassword"));
authenticator.setUserSearch(new MockUserSearch(user));
LdapUserDetailsImpl.Essence userEssence = new LdapUserDetailsImpl.Essence();
userEssence.setDn("uid=Bob,ou=people,dc=acegisecurity,dc=org");
userEssence.setPassword("bobspassword");
authenticator.setUserSearch(new MockUserSearch(userEssence.createUserDetails()));
authenticator.authenticate("ShouldntBeUsed","bobspassword");
}

View File

@@ -1,10 +1,9 @@
package org.acegisecurity.providers.ldap.populator;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.BasicAttribute;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
import org.acegisecurity.ldap.AbstractLdapServerTestCase;
import java.util.Set;
@@ -21,30 +20,39 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest
getInitialCtxFactory().setManagerPassword(MANAGER_PASSWORD);
}
public void testUserAttributeMappingToRoles() {
DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator();
populator.setUserRoleAttributes(new String[] {"userRole", "otherUserRole"});
populator.getUserRoleAttributes();
Attributes userAttrs = new BasicAttributes();
BasicAttribute attr = new BasicAttribute("userRole", "role1");
attr.add("role2");
userAttrs.put(attr);
attr = new BasicAttribute("otherUserRole", "role3");
attr.add("role2"); // duplicate
userAttrs.put(attr);
GrantedAuthority[] authorities =
populator.getGrantedAuthorities("Ignored", "Ignored", userAttrs);
assertEquals("User should have three roles", 3, authorities.length);
}
// public void testUserAttributeMappingToRoles() {
// DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator();
// populator.setUserRoleAttributes(new String[] {"userRole", "otherUserRole"});
// populator.getUserRoleAttributes();
//
// Attributes userAttrs = new BasicAttributes();
// BasicAttribute attr = new BasicAttribute("userRole", "role1");
// attr.add("role2");
// userAttrs.put(attr);
// attr = new BasicAttribute("otherUserRole", "role3");
// attr.add("role2"); // duplicate
// userAttrs.put(attr);
//
// LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
// user.setDn("Ignored");
// user.setUsername("Ignored");
// user.setAttributes(userAttrs);
//
// GrantedAuthority[] authorities =
// populator.getGrantedAuthorities(user.createUserDetails());
// assertEquals("User should have three roles", 3, authorities.length);
// }
public void testDefaultRoleIsAssignedWhenSet() {
DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator();
populator.setDefaultRole("ROLE_USER");
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
user.setDn("Ignored");
user.setUsername("Ignored");
user.setAttributes(new BasicAttributes());
GrantedAuthority[] authorities =
populator.getGrantedAuthorities("Ignored", "Ignored", new BasicAttributes());
populator.getGrantedAuthorities(user.createUserDetails());
assertEquals(1, authorities.length);
assertEquals("ROLE_USER", authorities[0].getAuthority());
}
@@ -59,9 +67,14 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapServerTest
populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(member={0})");
LdapUserDetailsImpl.Essence user = new LdapUserDetailsImpl.Essence();
user.setUsername("ben");
user.setDn("uid=ben,ou=people,dc=acegisecurity,dc=org");
user.setAttributes(new BasicAttributes());
GrantedAuthority[] authorities =
populator.getGrantedAuthorities("ben", "uid=ben,ou=people,"+
getInitialCtxFactory().getRootDn(), new BasicAttributes());
populator.getGrantedAuthorities(user.createUserDetails());
assertEquals("Should have 2 roles", 2, authorities.length);
Set roles = new HashSet();
roles.add(authorities[0].toString());