OPEN - issue SEC-789: Add support for optional role-prefix attribute to namespace

http://jira.springframework.org/browse/SEC-789. Added role-prefix attribute to ldap provider and jdbc/ldap user-service elements.
This commit is contained in:
Luke Taylor 2008-04-21 18:29:54 +00:00
parent aba5a22b6c
commit 9eaa1cbbdd
4 changed files with 65 additions and 16 deletions

View File

@ -28,6 +28,8 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
public static final String DEF_GROUP_SEARCH_FILTER = "(uniqueMember={0})"; public static final String DEF_GROUP_SEARCH_FILTER = "(uniqueMember={0})";
public static final String DEF_GROUP_SEARCH_BASE = "ou=groups"; public static final String DEF_GROUP_SEARCH_BASE = "ou=groups";
static final String ATT_ROLE_PREFIX = "role-prefix";
protected Class getBeanClass(Element element) { protected Class getBeanClass(Element element) {
return LdapUserDetailsService.class; return LdapUserDetailsService.class;
} }
@ -61,13 +63,13 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
return null; return null;
} }
RootBeanDefinition search = new RootBeanDefinition(FilterBasedLdapUserSearch.class); BeanDefinitionBuilder searchBuilder = BeanDefinitionBuilder.rootBeanDefinition(FilterBasedLdapUserSearch.class);
search.setSource(source); searchBuilder.setSource(source);
search.getConstructorArgumentValues().addIndexedArgumentValue(0, userSearchBase); searchBuilder.addConstructorArg(userSearchBase);
search.getConstructorArgumentValues().addIndexedArgumentValue(1, userSearchFilter); searchBuilder.addConstructorArg(userSearchFilter);
search.getConstructorArgumentValues().addIndexedArgumentValue(2, parseServerReference(elt, parserContext)); searchBuilder.addConstructorArg(parseServerReference(elt, parserContext));
return search; return (RootBeanDefinition) searchBuilder.getBeanDefinition();
} }
static RuntimeBeanReference parseServerReference(Element elt, ParserContext parserContext) { static RuntimeBeanReference parseServerReference(Element elt, ParserContext parserContext) {
@ -87,6 +89,7 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER); String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE); String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
String groupRoleAttribute = elt.getAttribute(ATT_GROUP_ROLE_ATTRIBUTE); String groupRoleAttribute = elt.getAttribute(ATT_GROUP_ROLE_ATTRIBUTE);
String rolePrefix = elt.getAttribute(ATT_ROLE_PREFIX);
if (!StringUtils.hasText(groupSearchFilter)) { if (!StringUtils.hasText(groupSearchFilter)) {
groupSearchFilter = DEF_GROUP_SEARCH_FILTER; groupSearchFilter = DEF_GROUP_SEARCH_FILTER;
@ -96,16 +99,23 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
groupSearchBase = DEF_GROUP_SEARCH_BASE; groupSearchBase = DEF_GROUP_SEARCH_BASE;
} }
RootBeanDefinition populator = new RootBeanDefinition(DefaultLdapAuthoritiesPopulator.class); BeanDefinitionBuilder populator = BeanDefinitionBuilder.rootBeanDefinition(DefaultLdapAuthoritiesPopulator.class);
populator.setSource(parserContext.extractSource(elt)); populator.setSource(parserContext.extractSource(elt));
populator.getConstructorArgumentValues().addIndexedArgumentValue(0, parseServerReference(elt, parserContext)); populator.addConstructorArg(parseServerReference(elt, parserContext));
populator.getConstructorArgumentValues().addIndexedArgumentValue(1, groupSearchBase); populator.addConstructorArg(groupSearchBase);
populator.getPropertyValues().addPropertyValue("groupSearchFilter", groupSearchFilter); populator.addPropertyValue("groupSearchFilter", groupSearchFilter);
if (StringUtils.hasText(rolePrefix)) {
if ("none".equals(rolePrefix)) {
rolePrefix = "";
}
populator.addPropertyValue("rolePrefix", rolePrefix);
}
if (StringUtils.hasLength(groupRoleAttribute)) { if (StringUtils.hasLength(groupRoleAttribute)) {
populator.getPropertyValues().addPropertyValue("groupRoleAttribute", groupRoleAttribute); populator.addPropertyValue("groupRoleAttribute", groupRoleAttribute);
} }
return populator; return (RootBeanDefinition) populator.getBeanDefinition();
} }
} }

View File

@ -113,7 +113,8 @@ ldap-us.attlist &=
group-role-attribute-attribute? group-role-attribute-attribute?
ldap-us.attlist &= ldap-us.attlist &=
cache-ref? cache-ref?
ldap-us.attlist &=
role-prefix?
ldap-authentication-provider = ldap-authentication-provider =
## Sets up an ldap authentication provider ## Sets up an ldap authentication provider
@ -133,6 +134,8 @@ ldap-ap.attlist &=
ldap-ap.attlist &= ldap-ap.attlist &=
## A specific pattern used to build the user's DN, for example "uid={0},ou=people". The key "{0}" must be present and will be substituted with the username. ## A specific pattern used to build the user's DN, for example "uid={0},ou=people". The key "{0}" must be present and will be substituted with the username.
attribute user-dn-pattern {xsd:string}? attribute user-dn-pattern {xsd:string}?
ldap-ap.attlist &=
role-prefix?
password-compare-element = password-compare-element =
## Specifies that an LDAP provider should use an LDAP compare operation of the user's password to authenticate the user ## Specifies that an LDAP provider should use an LDAP compare operation of the user's password to authenticate the user

View File

@ -297,6 +297,12 @@
UserDetailsService.</xs:documentation> UserDetailsService.</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="role-prefix" type="xs:string">
<xs:annotation>
<xs:documentation>A non-empty string prefix that will be added to role strings loaded from
persistent storage (e.g. "ROLE_").</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup> </xs:attributeGroup>
<xs:element name="ldap-authentication-provider"> <xs:element name="ldap-authentication-provider">
<xs:annotation> <xs:annotation>
@ -383,6 +389,12 @@
username.</xs:documentation> username.</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="role-prefix" type="xs:string">
<xs:annotation>
<xs:documentation>A non-empty string prefix that will be added to role strings loaded from
persistent storage (e.g. "ROLE_").</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup> </xs:attributeGroup>
<xs:attributeGroup name="password-compare.attlist"> <xs:attributeGroup name="password-compare.attlist">
<xs:attribute name="password-attribute" type="xs:string"> <xs:attribute name="password-attribute" type="xs:string">

View File

@ -41,12 +41,15 @@ public class LdapUserServiceBeanDefinitionParserTests {
Set authorities = AuthorityUtils.authorityArrayToSet(ben.getAuthorities()); Set authorities = AuthorityUtils.authorityArrayToSet(ben.getAuthorities());
assertEquals(2, authorities.size()); assertEquals(2, authorities.size());
assertTrue(authorities.contains(new GrantedAuthorityImpl("ROLE_DEVELOPERS"))); assertTrue(authorities.contains("ROLE_DEVELOPERS"));
} }
@Test @Test
public void differentUserSearchBaseWorksAsExpected() throws Exception { public void differentUserSearchBaseWorksAsExpected() throws Exception {
setContext("<ldap-user-service id='ldapUDS' user-search-base='ou=otherpeople' user-search-filter='(cn={0})' group-search-filter='member={0}' /><ldap-server />"); setContext("<ldap-user-service id='ldapUDS' " +
" user-search-base='ou=otherpeople' " +
" user-search-filter='(cn={0})' " +
" group-search-filter='member={0}' /><ldap-server />");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS"); UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails joe = uds.loadUserByUsername("Joe Smeth"); UserDetails joe = uds.loadUserByUsername("Joe Smeth");
@ -54,6 +57,27 @@ public class LdapUserServiceBeanDefinitionParserTests {
assertEquals("Joe Smeth", joe.getUsername()); assertEquals("Joe Smeth", joe.getUsername());
} }
@Test
public void rolePrefixIsSupported() throws Exception {
setContext(
"<ldap-user-service id='ldapUDS' " +
" user-search-filter='(uid={0})' " +
" group-search-filter='member={0}' role-prefix='PREFIX_'/>" +
"<ldap-user-service id='ldapUDSNoPrefix' " +
" user-search-filter='(uid={0})' " +
" group-search-filter='member={0}' role-prefix='none'/><ldap-server />");
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
UserDetails ben = uds.loadUserByUsername("ben");
assertTrue(AuthorityUtils.authorityArrayToSet(ben.getAuthorities()).contains("PREFIX_DEVELOPERS"));
uds = (UserDetailsService) appCtx.getBean("ldapUDSNoPrefix");
ben = uds.loadUserByUsername("ben");
assertTrue(AuthorityUtils.authorityArrayToSet(ben.getAuthorities()).contains("DEVELOPERS"));
}
@Test @Test
public void differentGroupRoleAttributeWorksAsExpected() throws Exception { public void differentGroupRoleAttributeWorksAsExpected() throws Exception {
setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server />"); setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server />");