SEC-619: Added test class for LdapUserDetailsService. The LdapAuthoritiesPopulator interface and also implementations have been moved to the org.springframework.security.ldap package since they are now used by both the ldap provider and the user service.

This commit is contained in:
Luke Taylor 2007-12-09 18:40:28 +00:00
parent 4770c29094
commit 5e0cb21c8d
14 changed files with 94 additions and 32 deletions

View File

@ -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;

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
package org.springframework.security.providers.ldap;
package org.springframework.security.ldap;
import org.springframework.security.GrantedAuthority;

View File

@ -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.
* <p>It obtains roles by performing a search for "groups" the user is a member of.</p>
* <p/>
* <p>
* It obtains roles by performing a search for "groups" the user is a member of.
* <p>
* A typical group search scenario would be where each group/role is specified using the <tt>groupOfNames</tt>
* (or <tt>groupOfUniqueNames</tt>) LDAP objectClass and the user's DN is listed in the <tt>member</tt> (or
* <tt>uniqueMember</tt>) 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
* </pre>
* </p>
* <p/>
* <p>
* The group search is performed within a DN specified by the <tt>groupSearchBase</tt> property, which should
* be relative to the root DN of its <tt>InitialDirContextFactory</tt>. If the search base is null, group searching is
* disabled. The filter used in the search is defined by the <tt>groupSearchFilter</tt> 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 <tt>groupRoleAttribute</tt> property (the default is "cn").</p>
* <p/>
* <p>The configuration below shows how the group search might be performed with the above schema.
* the <tt>groupRoleAttribute</tt> property (the default is "cn").
* <p>
* The configuration below shows how the group search might be performed with the above schema.
* <pre>
* &lt;bean id="ldapAuthoritiesPopulator"
* class="org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
@ -80,8 +80,7 @@ import java.util.Set;
* </pre>
* A search for roles for user "uid=ben,ou=people,dc=springframework,dc=org" would return the single granted authority
* "ROLE_DEVELOPER".
* </p>
* <p/>
* <p>
* The single-level search is performed by default. Setting the <tt>searchSubTree</tt> property to true will enable
* a search of the entire subtree under <tt>groupSearchBase</tt>.
*
@ -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

View File

@ -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;
* <h3>LdapAuthoritiesPopulator</h3>
* 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 =====================================================================================

View File

@ -24,7 +24,6 @@ import org.springframework.ldap.core.DirContextOperations;
*
* <p>
* The username will be mapped from the <tt>uid</tt> attribute by default.
* </p>
*
* @author Luke
* @version $Id$

View File

@ -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;

View File

@ -34,6 +34,9 @@ public class MockSpringSecurityContextSource implements SpringSecurityContextSou
//~ Constructors ===================================================================================================
public MockSpringSecurityContextSource() {
}
public MockSpringSecurityContextSource(DirContext ctx, String baseDn) {
this.baseDn = baseDn;
this.ctx = ctx;

View File

@ -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;

View File

@ -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;

View File

@ -33,6 +33,9 @@ public class MockUserSearch implements LdapUserSearch {
//~ Constructors ===================================================================================================
public MockUserSearch() {
}
public MockUserSearch(DirContextOperations user) {
this.user = user;
}

View File

@ -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")};
}
}
}

View File

@ -50,7 +50,7 @@
</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="contextSource"/></constructor-arg>
<constructor-arg><value>ou=groups</value></constructor-arg>
<property name="groupRoleAttribute"><value>ou</value></property>

View File

@ -1462,7 +1462,7 @@ if (obj instanceof UserDetails) {
Note that when using the tags, you should include the taglib reference
in your JSP: <programlisting>
&lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
</programlisting></para>
</sect1>
</chapter>
@ -3265,7 +3265,7 @@ key: A private key to prevent modification of the remember-me token
&lt;/bean&gt;
&lt;/constructor-arg&gt;
&lt;constructor-arg&gt;
&lt;bean class="org.springframework.security.providers.ldap.populator.DefaultLdapAuthoritiesPopulator"&gt;
&lt;bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator"&gt;
&lt;constructor-arg&gt;&lt;ref local="initialDirContextFactory"/&gt;&lt;/constructor-arg&gt;
&lt;constructor-arg&gt;&lt;value&gt;ou=groups&lt;/value&gt;&lt;/constructor-arg&gt;
&lt;property name="groupRoleAttribute"&gt;&lt;value&gt;ou&lt;/value&gt;&lt;/property&gt;