SEC-1677: Split out integration tests from LDAP test code.

This commit is contained in:
Luke Taylor
2011-02-11 17:55:16 +00:00
parent 9f8a47f73e
commit a225dc3776
13 changed files with 129 additions and 92 deletions

View File

@@ -1,127 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap;
import javax.naming.Binding;
import javax.naming.ContextNotEmptyException;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.ldap.server.ApacheDSContainer;
/**
* Based on class borrowed from Spring Ldap project.
*
* @author Luke Taylor
*/
public abstract class AbstractLdapIntegrationTests {
// private static InMemoryXmlApplicationContext appContext;
private static ApacheDSContainer server;
private static DefaultSpringSecurityContextSource contextSource;
protected AbstractLdapIntegrationTests() {
}
@BeforeClass
public static void startServer() throws Exception {
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
// OpenLDAP configuration
// contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
// contextSource.setPassword("password");
contextSource.afterPropertiesSet();
server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
server.afterPropertiesSet();
}
@AfterClass
public static void stopServer() throws Exception {
if (server != null) {
server.stop();
}
}
@Before
public void onSetUp() throws Exception {
}
@After
public final void reloadServerDataIfDirty() throws Exception {
ClassPathResource ldifs = new ClassPathResource("test-server.ldif");
if (!ldifs.getFile().exists()) {
throw new IllegalStateException("Ldif file not found: " + ldifs.getFile().getAbsolutePath());
}
DirContext ctx = getContextSource().getReadWriteContext();
// First of all, make sure the database is empty.
Name startingPoint = new DistinguishedName("dc=springframework,dc=org");
try {
clearSubContexts(ctx, startingPoint);
LdifFileLoader loader = new LdifFileLoader(server.getService().getAdminSession(), ldifs.getFile().getAbsolutePath());
loader.execute();
} finally {
ctx.close();
}
}
public BaseLdapPathContextSource getContextSource() {
return contextSource;
}
private void clearSubContexts(DirContext ctx, Name name) throws NamingException {
NamingEnumeration<Binding> enumeration = null;
try {
enumeration = ctx.listBindings(name);
while (enumeration.hasMore()) {
Binding element = enumeration.next();
DistinguishedName childName = new DistinguishedName(element.getName());
childName.prepend((DistinguishedName) name);
try {
ctx.destroySubcontext(childName);
} catch (ContextNotEmptyException e) {
clearSubContexts(ctx, childName);
ctx.destroySubcontext(childName);
}
}
} catch(NameNotFoundException ignored) {
}
catch (NamingException e) {
e.printStackTrace();
} finally {
try {
enumeration.close();
} catch (Exception ignored) {
}
}
}
}

View File

@@ -1,79 +0,0 @@
package org.springframework.security.ldap;
import static org.junit.Assert.*;
import java.util.Hashtable;
import javax.naming.directory.DirContext;
import org.junit.Test;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.core.support.AbstractContextSource;
/**
* @author Luke Taylor
*/
public class DefaultSpringSecurityContextSourceTests extends AbstractLdapIntegrationTests {
@Test
public void instantiationSucceedsWithExpectedProperties() {
DefaultSpringSecurityContextSource ctxSrc =
new DefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
assertFalse(ctxSrc.isAnonymousReadOnly());
assertTrue(ctxSrc.isPooled());
}
@Test
public void supportsSpacesInUrl() {
new DefaultSpringSecurityContextSource("ldap://myhost:10389/dc=spring%20framework,dc=org");
}
@Test
public void poolingFlagIsSetWhenAuthenticationDnMatchesManagerUserDn() throws Exception {
EnvExposingDefaultSpringSecurityContextSource ctxSrc =
new EnvExposingDefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
ctxSrc.setUserDn("manager");
ctxSrc.setPassword("password");
ctxSrc.afterPropertiesSet();
assertTrue(ctxSrc.getAuthenticatedEnvForTest("manager", "password").containsKey(AbstractContextSource.SUN_LDAP_POOLING_FLAG));
}
@Test
public void poolingFlagIsNotSetWhenAuthenticationDnIsNotManagerUserDn() throws Exception {
EnvExposingDefaultSpringSecurityContextSource ctxSrc =
new EnvExposingDefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
ctxSrc.setUserDn("manager");
ctxSrc.setPassword("password");
ctxSrc.afterPropertiesSet();
assertFalse(ctxSrc.getAuthenticatedEnvForTest("user", "password").containsKey(AbstractContextSource.SUN_LDAP_POOLING_FLAG));
}
// SEC-1145. Confirms that there is no issue here with pooling.
@Test(expected=AuthenticationException.class)
public void cantBindWithWrongPasswordImmediatelyAfterSuccessfulBind() throws Exception {
DirContext ctx = null;
try {
ctx = getContextSource().getContext("uid=Bob,ou=people,dc=springframework,dc=org", "bobspassword");
} catch (Exception e) {
}
assertNotNull(ctx);
// com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
ctx.close();
// com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
// Now get it gain, with wrong password. Should fail.
ctx = getContextSource().getContext("uid=Bob,ou=people,dc=springframework,dc=org", "wrongpassword");
}
static class EnvExposingDefaultSpringSecurityContextSource extends DefaultSpringSecurityContextSource {
public EnvExposingDefaultSpringSecurityContextSource(String providerUrl) {
super(providerUrl);
}
@SuppressWarnings("unchecked")
Hashtable getAuthenticatedEnvForTest(String userDn, String password) {
return getAuthenticatedEnv(userDn, password);
}
}
}

View File

@@ -1,150 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap;
import static org.junit.Assert.*;
import java.util.Set;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.junit.Test;
import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.core.ContextExecutor;
/**
* @author Luke Taylor
*/
public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTests {
//~ Instance fields ================================================================================================
private SpringSecurityLdapTemplate template;
//~ Methods ========================================================================================================
public void onSetUp() throws Exception {
super.onSetUp();
template = new SpringSecurityLdapTemplate(getContextSource());
}
@Test
public void compareOfCorrectValueSucceeds() {
assertTrue(template.compare("uid=bob,ou=people", "uid", "bob"));
}
@Test
public void compareOfCorrectByteValueSucceeds() {
assertTrue(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("bobspassword")));
}
@Test
public void compareOfWrongByteValueFails() {
assertFalse(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue")));
}
@Test
public void compareOfWrongValueFails() {
assertFalse(template.compare("uid=bob,ou=people", "uid", "wrongvalue"));
}
// @Test
// public void testNameExistsForInValidNameFails() {
// assertFalse(template.nameExists("ou=doesntexist,dc=springframework,dc=org"));
// }
//
// @Test
// public void testNameExistsForValidNameSucceeds() {
// assertTrue(template.nameExists("ou=groups,dc=springframework,dc=org"));
// }
@Test
public void namingExceptionIsTranslatedCorrectly() {
try {
template.executeReadOnly(new ContextExecutor() {
public Object executeWithContext(DirContext dirContext) throws NamingException {
throw new NamingException();
}
});
fail("Expected UncategorizedLdapException on NamingException");
} catch (UncategorizedLdapException expected) {}
}
@Test
public void roleSearchReturnsCorrectNumberOfRoles() {
String param = "uid=ben,ou=people,dc=springframework,dc=org";
Set<String> values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "ou");
assertEquals("Expected 3 results from search", 3, values.size());
assertTrue(values.contains("developer"));
assertTrue(values.contains("manager"));
assertTrue(values.contains("submanager"));
}
@Test
public void testRoleSearchForMissingAttributeFailsGracefully() {
String param = "uid=ben,ou=people,dc=springframework,dc=org";
Set<String> values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "mail");
assertEquals(0, values.size());
}
@Test
public void roleSearchWithEscapedCharacterSucceeds() throws Exception {
String param = "cn=mouse\\, jerry,ou=people,dc=springframework,dc=org";
Set<String> values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "cn");
assertEquals(1, values.size());
}
@Test
public void nonSpringLdapSearchCodeTestMethod() throws Exception {
java.util.Hashtable<String, String> env = new java.util.Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:53389");
env.put(Context.SECURITY_PRINCIPAL, "");
env.put(Context.SECURITY_CREDENTIALS, "");
DirContext ctx = new javax.naming.directory.InitialDirContext(env);
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningObjFlag(true);
controls.setReturningAttributes(null);
String param = "cn=mouse\\, jerry,ou=people,dc=springframework,dc=org";
javax.naming.NamingEnumeration<SearchResult> results =
ctx.search("ou=groups,dc=springframework,dc=org",
"(member={0})", new String[] {param},
controls);
assertTrue("Expected a result", results.hasMore());
}
@Test
public void searchForSingleEntryWithEscapedCharsInDnSucceeds() {
String param = "mouse, jerry";
template.searchForSingleEntry("ou=people", "(cn={0})", new String[] {param});
}
}

View File

@@ -1,128 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.authentication;
import static org.junit.Assert.*;
import org.junit.*;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
/**
* Tests for {@link BindAuthenticator}.
*
* @author Luke Taylor
*/
public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
//~ Instance fields ================================================================================================
private BindAuthenticator authenticator;
private Authentication bob;
//~ Methods ========================================================================================================
public void onSetUp() {
authenticator = new BindAuthenticator(getContextSource());
authenticator.setMessageSource(new SpringSecurityMessageSource());
bob = new UsernamePasswordAuthenticationToken("bob", "bobspassword");
}
@Test(expected=BadCredentialsException.class)
public void emptyPasswordIsRejected() {
authenticator.authenticate(new UsernamePasswordAuthenticationToken("jen", ""));
}
@Test
public void testAuthenticationWithCorrectPasswordSucceeds() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
DirContextOperations user = authenticator.authenticate(bob);
assertEquals("bob", user.getStringAttribute("uid"));
}
@Test
public void testAuthenticationWithInvalidUserNameFails() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
try {
authenticator.authenticate(new UsernamePasswordAuthenticationToken("nonexistentsuser", "password"));
fail("Shouldn't be able to bind with invalid username");
} catch (BadCredentialsException expected) {}
}
@Test
public void testAuthenticationWithUserSearch() throws Exception {
//DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=bob,ou=people"));
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people", "(uid={0})", getContextSource()));
authenticator.afterPropertiesSet();
authenticator.authenticate(bob);
// SEC-1444
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people", "(cn={0})", getContextSource()));
authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword"));
authenticator.authenticate(new UsernamePasswordAuthenticationToken("slash/guy", "slashguyspassword"));
// SEC-1661
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=\\\"quoted people\\\"", "(cn={0})", getContextSource()));
authenticator.authenticate(new UsernamePasswordAuthenticationToken("quote\"guy", "quoteguyspassword"));
authenticator.setUserSearch(new FilterBasedLdapUserSearch("", "(cn={0})", getContextSource()));
authenticator.authenticate(new UsernamePasswordAuthenticationToken("quote\"guy", "quoteguyspassword"));
}
/*
@Test
public void messingWithEscapedChars() throws Exception {
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://127.0.0.1:22389/dc=springsource,dc=com");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=springsource,dc=com");
env.put(Context.SECURITY_CREDENTIALS, "password");
InitialDirContext idc = new InitialDirContext(env);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
DistinguishedName baseDn = new DistinguishedName("ou=\\\"quoted people\\\"");
NamingEnumeration<SearchResult> matches = idc.search(baseDn, "(cn=*)", new Object[] {"quoteguy"}, searchControls);
while(matches.hasMore()) {
SearchResult match = matches.next();
DistinguishedName dn = new DistinguishedName(match.getName());
System.out.println("**** Match: " + match.getName() + " ***** " + dn);
}
}
*/
@Test
public void testAuthenticationWithWrongPasswordFails() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
try {
authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "wrongpassword"));
fail("Shouldn't be able to bind with wrong password");
} catch (BadCredentialsException expected) {}
}
@Test
public void testUserDnPatternReturnsCorrectDn() {
authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"});
assertEquals("cn=Joe,ou=people", authenticator.getUserDns("Joe").get(0));
}
}

View File

@@ -1,143 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.authentication;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Tests for {@link PasswordComparisonAuthenticator}.
*
* @author Luke Taylor
*/
public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegrationTests {
//~ Instance fields ================================================================================================
private PasswordComparisonAuthenticator authenticator;
private Authentication bob;
private Authentication ben;
//~ Methods ========================================================================================================
public void onSetUp() throws Exception {
super.onSetUp();
authenticator = new PasswordComparisonAuthenticator(getContextSource());
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
bob = new UsernamePasswordAuthenticationToken("bob", "bobspassword");
ben = new UsernamePasswordAuthenticationToken("ben", "benspassword");
}
@Test
public void testAllAttributesAreRetrievedByDefault() {
DirContextAdapter user = (DirContextAdapter) authenticator.authenticate(bob);
//System.out.println(user.getAttributes().toString());
assertEquals("User should have 5 attributes", 5, user.getAttributes().size());
}
@Test
public void testFailedSearchGivesUserNotFoundException() throws Exception {
authenticator = new PasswordComparisonAuthenticator(getContextSource());
assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty());
authenticator.setUserSearch(new MockUserSearch(null));
authenticator.afterPropertiesSet();
try {
authenticator.authenticate(new UsernamePasswordAuthenticationToken("Joe", "pass"));
fail("Expected exception on failed user search");
} catch (UsernameNotFoundException expected) {}
}
@Test(expected = BadCredentialsException.class)
public void testLdapPasswordCompareFailsWithWrongPassword() {
// Don't retrieve the password
authenticator.setUserAttributes(new String[] {"uid", "cn", "sn"});
authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "wrongpass"));
}
@Test
public void testMultipleDnPatternsWorkOk() {
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=nonexistent", "uid={0},ou=people"});
authenticator.authenticate(bob);
}
@Test
public void testOnlySpecifiedAttributesAreRetrieved() throws Exception {
authenticator.setUserAttributes(new String[] {"uid", "userPassword"});
DirContextAdapter user = (DirContextAdapter) authenticator.authenticate(bob);
assertEquals("Should have retrieved 2 attribute (uid, userPassword)", 2, user.getAttributes().size());
}
@Test
public void testLdapCompareSucceedsWithCorrectPassword() {
// Don't retrieve the password
authenticator.setUserAttributes(new String[] {"uid"});
authenticator.authenticate(bob);
}
@Test
public void testLdapCompareSucceedsWithShaEncodedPassword() {
// Don't retrieve the password
authenticator.setUserAttributes(new String[] {"uid"});
authenticator.setPasswordEncoder(new LdapShaPasswordEncoder());
authenticator.authenticate(ben);
}
@Test(expected = IllegalArgumentException.class)
public void testPasswordEncoderCantBeNull() {
authenticator.setPasswordEncoder(null);
}
@Test
public void testUseOfDifferentPasswordAttributeSucceeds() {
authenticator.setPasswordAttributeName("uid");
authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "bob"));
}
@Test
public void testLdapCompareWithDifferentPasswordAttributeSucceeds() {
authenticator.setUserAttributes(new String[] {"uid"});
authenticator.setPasswordAttributeName("cn");
authenticator.authenticate(new UsernamePasswordAuthenticationToken("ben", "Ben Alex"));
}
@Test
public void testWithUserSearch() {
authenticator = new PasswordComparisonAuthenticator(getContextSource());
authenticator.setPasswordEncoder(new PlaintextPasswordEncoder());
assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty());
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=Bob,ou=people"));
ctx.setAttributeValue("userPassword", "bobspassword");
authenticator.setUserSearch(new MockUserSearch(ctx));
authenticator.authenticate(new UsernamePasswordAuthenticationToken("shouldntbeused", "bobspassword"));
}
}

View File

@@ -1,111 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.search;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* Tests for FilterBasedLdapUserSearch.
*
* @author Luke Taylor
*/
public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests {
//~ Instance fields ================================================================================================
private BaseLdapPathContextSource dirCtxFactory;
//~ Methods ========================================================================================================
public void onSetUp() throws Exception {
super.onSetUp();
dirCtxFactory = getContextSource();
}
@Test
public void basicSearchSucceeds() {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory);
locator.setSearchSubtree(false);
locator.setSearchTimeLimit(0);
locator.setDerefLinkFlag(false);
DirContextOperations bob = locator.searchForUser("bob");
assertEquals("bob", bob.getStringAttribute("uid"));
assertEquals(new DistinguishedName("uid=bob,ou=people"), bob.getDn());
}
@Test
public void searchForNameWithCommaSucceeds() {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory);
locator.setSearchSubtree(false);
DirContextOperations jerry = locator.searchForUser("jerry");
assertEquals("jerry", jerry.getStringAttribute("uid"));
assertEquals(new DistinguishedName("cn=mouse\\, jerry,ou=people"), jerry.getDn());
}
// Try some funny business with filters.
@Test
public void extraFilterPartToExcludeBob() throws Exception {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people",
"(&(cn=*)(!(|(uid={0})(uid=rod)(uid=jerry)(uid=slashguy))))", dirCtxFactory);
// Search for bob, get back ben...
DirContextOperations ben = locator.searchForUser("bob");
assertEquals("Ben Alex", ben.getStringAttribute("cn"));
}
@Test(expected=IncorrectResultSizeDataAccessException.class)
public void searchFailsOnMultipleMatches() {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(cn=*)", dirCtxFactory);
locator.searchForUser("Ignored");
}
@Test(expected=UsernameNotFoundException.class)
public void searchForInvalidUserFails() {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory);
locator.searchForUser("Joe");
}
@Test
public void subTreeSearchSucceeds() {
// Don't set the searchBase, so search from the root.
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory);
locator.setSearchSubtree(true);
DirContextOperations ben = locator.searchForUser("Ben Alex");
assertEquals("ben", ben.getStringAttribute("uid"));
assertEquals(new DistinguishedName("uid=ben,ou=people"), ben.getDn());
}
@Test
public void searchWithDifferentSearchBaseIsSuccessful() throws Exception {
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=otherpeople", "(cn={0})", dirCtxFactory);
DirContextOperations joe = locator.searchForUser("Joe Smeth");
assertEquals("Joe Smeth", joe.getStringAttribute("cn"));
}
}

View File

@@ -1,26 +0,0 @@
package org.springframework.security.ldap.server;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.junit.Test;
/**
* Useful for debugging the container by itself.
*
* @author Luke Taylor
* @since 3.0
*/
public class ApacheDSContainerTests {
@Test
public void successfulStartupAndShutdown() throws Exception {
LdapDN people = new LdapDN("ou=people,dc=springframework,dc=org");
people.toString();
// ApacheDSContainer server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
// server.afterPropertiesSet();
//
// server.getService().getAdminSession().lookup(people);
//
// server.stop();
}
}

View File

@@ -1,162 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.userdetails;
import static org.junit.Assert.*;
import org.junit.*;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import java.util.*;
/**
*
* @author Luke Taylor
*/
@SuppressWarnings({"deprecation"})
public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegrationTests {
private DefaultLdapAuthoritiesPopulator populator;
//~ Methods ========================================================================================================
public void onSetUp() throws Exception {
super.onSetUp();
populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), "ou=groups");
populator.setIgnorePartialResultException(false);
}
@Test
public void defaultRoleIsAssignedWhenSet() {
populator.setDefaultRole("ROLE_USER");
assertSame(getContextSource(), populator.getContextSource());
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("cn=notfound"));
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "notfound");
assertEquals(1, authorities.size());
assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_USER"));
}
@Test
public void nullSearchBaseIsAccepted() throws Exception {
populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), null);
populator.setDefaultRole("ROLE_USER");
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(
new DirContextAdapter(new DistinguishedName("cn=notused")), "notused");
assertEquals(1, authorities.size());
assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_USER"));
}
@Test
public void groupSearchReturnsExpectedRoles() {
populator.setRolePrefix("ROLE_");
populator.setGroupRoleAttribute("ou");
populator.setSearchSubtree(true);
populator.setSearchSubtree(false);
populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(member={0})");
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "ben"));
assertEquals("Should have 2 roles", 2, authorities.size());
assertTrue(authorities.contains("ROLE_DEVELOPER"));
assertTrue(authorities.contains("ROLE_MANAGER"));
}
@Test
public void useOfUsernameParameterReturnsExpectedRoles() {
populator.setGroupRoleAttribute("ou");
populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(ou={1})");
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
assertEquals("Should have 1 role", 1, authorities.size());
assertTrue(authorities.contains("ROLE_MANAGER"));
}
@Test
public void subGroupRolesAreNotFoundByDefault() {
populator.setGroupRoleAttribute("ou");
populator.setConvertToUpperCase(true);
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
assertEquals("Should have 2 roles", 2, authorities.size());
assertTrue(authorities.contains("ROLE_MANAGER"));
assertTrue(authorities.contains("ROLE_DEVELOPER"));
}
@Test
public void subGroupRolesAreFoundWhenSubtreeSearchIsEnabled() {
populator.setGroupRoleAttribute("ou");
populator.setConvertToUpperCase(true);
populator.setSearchSubtree(true);
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
assertEquals("Should have 3 roles", 3, authorities.size());
assertTrue(authorities.contains("ROLE_MANAGER"));
assertTrue(authorities.contains("ROLE_SUBMANAGER"));
assertTrue(authorities.contains("ROLE_DEVELOPER"));
}
@Test
public void extraRolesAreAdded() throws Exception {
populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), null) {
@Override
protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) {
return new HashSet<GrantedAuthority>(AuthorityUtils.createAuthorityList("ROLE_EXTRA"));
}
};
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(
new DirContextAdapter(new DistinguishedName("cn=notused")), "notused");
assertEquals(1, authorities.size());
assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_EXTRA"));
}
@Test
public void userDnWithEscapedCharacterParameterReturnsExpectedRoles() {
populator.setGroupRoleAttribute("ou");
populator.setConvertToUpperCase(true);
populator.setGroupSearchFilter("(member={0})");
DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("cn=mouse\\, jerry,ou=people,dc=springframework,dc=org"));
Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "notused"));
assertEquals("Should have 1 role", 1, authorities.size());
assertTrue(authorities.contains("ROLE_MANAGER"));
}
}

View File

@@ -1,214 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.userdetails;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
import org.springframework.security.ldap.userdetails.InetOrgPerson;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import org.springframework.security.ldap.userdetails.LdapUserDetails;
import org.springframework.security.ldap.userdetails.LdapUserDetailsManager;
import org.springframework.security.ldap.userdetails.PersonContextMapper;
/**
* @author Luke Taylor
*/
public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
private static final List<GrantedAuthority> TEST_AUTHORITIES = AuthorityUtils.createAuthorityList("ROLE_CLOWNS","ROLE_ACROBATS");
private LdapUserDetailsManager mgr;
private SpringSecurityLdapTemplate template;
public void onSetUp() throws Exception {
super.onSetUp();
mgr = new LdapUserDetailsManager(getContextSource());
template = new SpringSecurityLdapTemplate(getContextSource());
DirContextAdapter ctx = new DirContextAdapter();
ctx.setAttributeValue("objectclass", "organizationalUnit");
ctx.setAttributeValue("ou", "test people");
template.bind("ou=test people", ctx, null);
ctx.setAttributeValue("ou", "testgroups");
template.bind("ou=testgroups", ctx, null);
DirContextAdapter group = new DirContextAdapter();
group.setAttributeValue("objectclass", "groupOfNames");
group.setAttributeValue("cn", "clowns");
group.setAttributeValue("member", "cn=nobody,ou=test people,dc=springframework,dc=org");
template.bind("cn=clowns,ou=testgroups", group, null);
group.setAttributeValue("cn", "acrobats");
template.bind("cn=acrobats,ou=testgroups", group, null);
mgr.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=test people","uid"));
mgr.setGroupSearchBase("ou=testgroups");
mgr.setGroupRoleAttributeName("cn");
mgr.setGroupMemberAttributeName("member");
mgr.setUserDetailsMapper(new PersonContextMapper());
}
@After
public void onTearDown() throws Exception {
// Iterator people = template.list("ou=testpeople").iterator();
// DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn()));
//
// while(people.hasNext()) {
// template.unbind((String) people.next() + ",ou=testpeople");
// }
template.unbind("ou=test people",true);
template.unbind("ou=testgroups",true);
SecurityContextHolder.clearContext();
}
@Test
public void testLoadUserByUsernameReturnsCorrectData() {
mgr.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=people","uid"));
mgr.setGroupSearchBase("ou=groups");
LdapUserDetails bob = (LdapUserDetails) mgr.loadUserByUsername("bob");
assertEquals("bob", bob.getUsername());
assertEquals("uid=bob,ou=people,dc=springframework,dc=org", bob.getDn());
assertEquals("bobspassword", bob.getPassword());
assertEquals(1, bob.getAuthorities().size());
}
@Test(expected = UsernameNotFoundException.class)
public void testLoadingInvalidUsernameThrowsUsernameNotFoundException() {
mgr.loadUserByUsername("jim");
}
@Test
public void testUserExistsReturnsTrueForValidUser() {
mgr.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=people","uid"));
assertTrue(mgr.userExists("bob"));
}
@Test
public void testUserExistsReturnsFalseForInValidUser() {
assertFalse(mgr.userExists("jim"));
}
@Test
public void testCreateNewUserSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setCarLicense("XXX");
p.setCn(new String[] {"Joe Smeth"});
p.setDepartmentNumber("5679");
p.setDescription("Some description");
p.setDn("whocares");
p.setEmployeeNumber("E781");
p.setInitials("J");
p.setMail("joe@smeth.com");
p.setMobile("+44776542911");
p.setOu("Joes Unit");
p.setO("Organization");
p.setRoomNumber("500X");
p.setSn("Smeth");
p.setUid("joe");
p.setAuthorities(TEST_AUTHORITIES);
mgr.createUser(p.createUserDetails());
}
@Test
public void testDeleteUserSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
p.setCn(new String[] {"Don Smeth"});
p.setSn("Smeth");
p.setUid("don");
p.setAuthorities(TEST_AUTHORITIES);
mgr.createUser(p.createUserDetails());
mgr.setUserDetailsMapper(new InetOrgPersonContextMapper());
InetOrgPerson don = (InetOrgPerson) mgr.loadUserByUsername("don");
assertEquals(2, don.getAuthorities().size());
mgr.deleteUser("don");
try {
mgr.loadUserByUsername("don");
fail("Expected UsernameNotFoundException after deleting user");
} catch(UsernameNotFoundException expected) {
// expected
}
// Check that no authorities are left
assertEquals(0, mgr.getUserAuthorities(mgr.usernameMapper.buildDn("don"), "don").size());
}
@Test
public void testPasswordChangeWithCorrectOldPasswordSucceeds() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
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));
mgr.changePassword("yossarianspassword", "yossariansnewpassword");
assertTrue(template.compare("uid=johnyossarian,ou=test people",
"userPassword", "yossariansnewpassword"));
}
@Test(expected = BadCredentialsException.class)
public void testPasswordChangeWithWrongOldPasswordFails() {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setDn("whocares");
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));
mgr.changePassword("wrongpassword", "yossariansnewpassword");
}
}