diff --git a/core/src/main/java/org/springframework/security/config/LdapBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/LdapBeanDefinitionParser.java index b7cbf1fe8d..47e8e596ec 100644 --- a/core/src/main/java/org/springframework/security/config/LdapBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/LdapBeanDefinitionParser.java @@ -1,9 +1,9 @@ package org.springframework.security.config; import org.springframework.security.ldap.DefaultSpringSecurityContextSource; +import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator; import org.springframework.security.providers.ldap.LdapAuthenticationProvider; import org.springframework.security.providers.ldap.authenticator.BindAuthenticator; -import org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; diff --git a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/ldap/LdapAuthoritiesPopulator.java similarity index 96% rename from core/src/main/java/org/springframework/security/providers/ldap/LdapAuthoritiesPopulator.java rename to core/src/main/java/org/springframework/security/ldap/LdapAuthoritiesPopulator.java index e30a0391d4..4e7c48fa04 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthoritiesPopulator.java +++ b/core/src/main/java/org/springframework/security/ldap/LdapAuthoritiesPopulator.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package org.springframework.security.providers.ldap; +package org.springframework.security.ldap; import org.springframework.security.GrantedAuthority; diff --git a/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulator.java similarity index 95% rename from core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java rename to core/src/main/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulator.java index 2fba78fa83..d460cbd2d6 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java +++ b/core/src/main/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulator.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package org.springframework.security.providers.ldap.populator; +package org.springframework.security.ldap.populator; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.ldap.SpringSecurityLdapTemplate; -import org.springframework.security.providers.ldap.LdapAuthoritiesPopulator; +import org.springframework.security.ldap.LdapAuthoritiesPopulator; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.DirContextOperations; import org.springframework.util.Assert; @@ -34,8 +34,9 @@ import java.util.Set; /** * The default strategy for obtaining user role information from the directory. - *

It obtains roles by performing a search for "groups" the user is a member of.

- *

+ *

+ * It obtains roles by performing a search for "groups" the user is a member of. + *

* A typical group search scenario would be where each group/role is specified using the groupOfNames * (or groupOfUniqueNames) LDAP objectClass and the user's DN is listed in the member (or * uniqueMember) attribute to indicate that they should be assigned that role. The following LDIF sample has @@ -48,7 +49,7 @@ import java.util.Set; * ou: groups * * dn: cn=developers,ou=groups,dc=springframework,dc=org - * objectClass: groupOfNameso + * objectClass: groupOfNames * objectClass: top * cn: developers * description: Spring Security Developers @@ -56,16 +57,15 @@ import java.util.Set; * member: uid=luke,ou=people,dc=springframework,dc=org * ou: developer * - *

- *

+ *

* The group search is performed within a DN specified by the groupSearchBase property, which should * be relative to the root DN of its InitialDirContextFactory. If the search base is null, group searching is * disabled. The filter used in the search is defined by the groupSearchFilter property, with the filter * argument {0} being the full DN of the user. You can also optionally use the parameter {1}, which will be substituted * with the username. You can also specify which attribute defines the role name by setting - * the groupRoleAttribute property (the default is "cn").

- *

- *

The configuration below shows how the group search might be performed with the above schema. + * the groupRoleAttribute property (the default is "cn"). + *

+ * The configuration below shows how the group search might be performed with the above schema. *

  * <bean id="ldapAuthoritiesPopulator"
  *       class="org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
@@ -80,8 +80,7 @@ import java.util.Set;
  * 
* A search for roles for user "uid=ben,ou=people,dc=springframework,dc=org" would return the single granted authority * "ROLE_DEVELOPER". - *

- *

+ *

* The single-level search is performed by default. Setting the searchSubTree property to true will enable * a search of the entire subtree under groupSearchBase. * @@ -98,9 +97,9 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator /** * A default role which will be assigned to all authenticated users if set */ - private GrantedAuthority defaultRole = null; + private GrantedAuthority defaultRole; - private ContextSource contextSource = null; + private ContextSource contextSource; private SpringSecurityLdapTemplate ldapTemplate; @@ -118,7 +117,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator /** * The base DN from which the search for group membership should be performed */ - private String groupSearchBase = null; + private String groupSearchBase; /** * The pattern to be used for the user search. {0} is the user's DN diff --git a/core/src/main/java/org/springframework/security/providers/ldap/populator/package.html b/core/src/main/java/org/springframework/security/ldap/populator/package.html similarity index 88% rename from core/src/main/java/org/springframework/security/providers/ldap/populator/package.html rename to core/src/main/java/org/springframework/security/ldap/populator/package.html index 2571b3e762..492914683e 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/populator/package.html +++ b/core/src/main/java/org/springframework/security/ldap/populator/package.html @@ -2,4 +2,4 @@ LdapAuthoritiesPopulator implementations. - + \ No newline at end of file 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 d49c2af204..c7f2fcc4f0 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 @@ -21,6 +21,8 @@ import org.springframework.security.AuthenticationServiceException; import org.springframework.security.BadCredentialsException; import org.springframework.security.GrantedAuthority; import org.springframework.security.SpringSecurityMessageSource; +import org.springframework.security.ldap.LdapAuthoritiesPopulator; +import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator; import org.springframework.security.providers.AuthenticationProvider; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.userdetails.UserDetails; @@ -60,7 +62,7 @@ import org.apache.commons.logging.LogFactory; *

LdapAuthoritiesPopulator

* Once the user has been authenticated, this interface is called to obtain the set of granted authorities for the * user. - * The {@link org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator DefaultLdapAuthoritiesPopulator} + * The {@link DefaultLdapAuthoritiesPopulator DefaultLdapAuthoritiesPopulator} * can be configured to obtain user role information from the user's attributes and/or to perform a search for * "groups" that the user is a member of and map these to roles. * @@ -114,7 +116,7 @@ import org.apache.commons.logging.LogFactory; * @version $Id$ * * @see org.springframework.security.providers.ldap.authenticator.BindAuthenticator - * @see org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator + * @see DefaultLdapAuthoritiesPopulator */ public class LdapAuthenticationProvider implements AuthenticationProvider { //~ Static fields/initializers ===================================================================================== diff --git a/core/src/main/java/org/springframework/security/userdetails/ldap/InetOrgPerson.java b/core/src/main/java/org/springframework/security/userdetails/ldap/InetOrgPerson.java index bdb53ac928..36f759e0d9 100644 --- a/core/src/main/java/org/springframework/security/userdetails/ldap/InetOrgPerson.java +++ b/core/src/main/java/org/springframework/security/userdetails/ldap/InetOrgPerson.java @@ -24,7 +24,6 @@ import org.springframework.ldap.core.DirContextOperations; * *

* The username will be mapped from the uid attribute by default. - *

* * @author Luke * @version $Id$ diff --git a/core/src/main/java/org/springframework/security/userdetails/ldap/LdapUserDetailsService.java b/core/src/main/java/org/springframework/security/userdetails/ldap/LdapUserDetailsService.java index e07cc5206c..ba2ff00b06 100644 --- a/core/src/main/java/org/springframework/security/userdetails/ldap/LdapUserDetailsService.java +++ b/core/src/main/java/org/springframework/security/userdetails/ldap/LdapUserDetailsService.java @@ -2,7 +2,7 @@ package org.springframework.security.userdetails.ldap; import org.springframework.security.GrantedAuthority; import org.springframework.security.ldap.LdapUserSearch; -import org.springframework.security.providers.ldap.LdapAuthoritiesPopulator; +import org.springframework.security.ldap.LdapAuthoritiesPopulator; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsService; import org.springframework.security.userdetails.UsernameNotFoundException; diff --git a/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java b/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java index 7a7ed644e0..8a0276857c 100644 --- a/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java +++ b/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java @@ -34,6 +34,9 @@ public class MockSpringSecurityContextSource implements SpringSecurityContextSou //~ Constructors =================================================================================================== + public MockSpringSecurityContextSource() { + } + public MockSpringSecurityContextSource(DirContext ctx, String baseDn) { this.baseDn = baseDn; this.ctx = ctx; diff --git a/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java b/core/src/test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java similarity index 97% rename from core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java rename to core/src/test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java index 636bc9db68..2a28674427 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java +++ b/core/src/test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java @@ -13,11 +13,12 @@ * limitations under the License. */ -package org.springframework.security.providers.ldap.populator; +package org.springframework.security.ldap.populator; import org.springframework.security.GrantedAuthority; import org.springframework.security.ldap.AbstractLdapIntegrationTests; +import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DistinguishedName; 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 814b206888..eed4182e5d 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 @@ -15,21 +15,20 @@ package org.springframework.security.providers.ldap; -import junit.framework.TestCase; - +import org.springframework.security.Authentication; import org.springframework.security.BadCredentialsException; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; -import org.springframework.security.Authentication; - +import org.springframework.security.ldap.LdapAuthoritiesPopulator; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; - import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.ldap.LdapUserDetailsMapper; -import org.springframework.ldap.core.DirContextOperations; import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DirContextOperations; import org.springframework.ldap.core.DistinguishedName; +import junit.framework.TestCase; + import java.util.ArrayList; diff --git a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/MockUserSearch.java b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/MockUserSearch.java index 6e7d6ddad9..51f310df9b 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/MockUserSearch.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/MockUserSearch.java @@ -33,6 +33,9 @@ public class MockUserSearch implements LdapUserSearch { //~ Constructors =================================================================================================== + public MockUserSearch() { + } + public MockUserSearch(DirContextOperations user) { this.user = user; } diff --git a/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsServiceTests.java b/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsServiceTests.java new file mode 100644 index 0000000000..d997a3a36e --- /dev/null +++ b/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsServiceTests.java @@ -0,0 +1,56 @@ +package org.springframework.security.userdetails.ldap; + +import org.springframework.security.GrantedAuthority; +import org.springframework.security.GrantedAuthorityImpl; +import org.springframework.security.ldap.LdapAuthoritiesPopulator; +import org.springframework.security.providers.ldap.authenticator.MockUserSearch; +import org.springframework.security.userdetails.UserDetails; +import org.springframework.security.util.AuthorityUtils; +import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DirContextOperations; +import org.springframework.ldap.core.DistinguishedName; + +import static org.junit.Assert.*; +import org.junit.Test; + +import java.util.Set; + +/** + * Tests for {@link LdapUserDetailsService} + * + * @author Luke Taylor + * @version $Id$ + */ +public class LdapUserDetailsServiceTests { + + @Test(expected = IllegalArgumentException.class) + public void rejectsNullSearchObject() { + new LdapUserDetailsService(null, new MockAuthoritiesPopulator()); + } + + @Test(expected = IllegalArgumentException.class) + public void rejectsNullAuthoritiesPopulator() { + new LdapUserDetailsService(new MockUserSearch(), null); + } + + @Test + public void correctAuthoritiesAreReturned() { + DirContextAdapter userData = new DirContextAdapter(new DistinguishedName("uid=joe")); + + LdapUserDetailsService service = + new LdapUserDetailsService(new MockUserSearch(userData), new MockAuthoritiesPopulator()); + service.setUserDetailsMapper(new LdapUserDetailsMapper()); + + UserDetails user = service.loadUserByUsername("doesntmatterwegetjoeanyway"); + + Set authorities = AuthorityUtils.authorityArrayToSet(user.getAuthorities()); + assertEquals(1, authorities.size()); + assertTrue(authorities.contains("ROLE_FROM_POPULATOR")); + } + + class MockAuthoritiesPopulator implements LdapAuthoritiesPopulator { + public GrantedAuthority[] getGrantedAuthorities(DirContextOperations userCtx, String username) { + return new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FROM_POPULATOR")}; + } + } +} diff --git a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml index 0343d64980..38911d41ed 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml @@ -50,7 +50,7 @@ - + ou=groups ou diff --git a/src/docbkx/springsecurity.xml b/src/docbkx/springsecurity.xml index d8d8a985c1..004546a61c 100644 --- a/src/docbkx/springsecurity.xml +++ b/src/docbkx/springsecurity.xml @@ -1462,7 +1462,7 @@ if (obj instanceof UserDetails) { Note that when using the tags, you should include the taglib reference in your JSP: <%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %> - + @@ -3265,7 +3265,7 @@ key: A private key to prevent modification of the remember-me token </bean> </constructor-arg> <constructor-arg> - <bean class="org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator"> + <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator"> <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg> <constructor-arg><value>ou=groups</value></constructor-arg> <property name="groupRoleAttribute"><value>ou</value></property>