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:
parent
aba5a22b6c
commit
9eaa1cbbdd
|
@ -27,6 +27,8 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||
public static final String ATT_GROUP_ROLE_ATTRIBUTE = "group-role-attribute";
|
||||
public static final String DEF_GROUP_SEARCH_FILTER = "(uniqueMember={0})";
|
||||
public static final String DEF_GROUP_SEARCH_BASE = "ou=groups";
|
||||
|
||||
static final String ATT_ROLE_PREFIX = "role-prefix";
|
||||
|
||||
protected Class getBeanClass(Element element) {
|
||||
return LdapUserDetailsService.class;
|
||||
|
@ -61,13 +63,13 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||
return null;
|
||||
}
|
||||
|
||||
RootBeanDefinition search = new RootBeanDefinition(FilterBasedLdapUserSearch.class);
|
||||
search.setSource(source);
|
||||
search.getConstructorArgumentValues().addIndexedArgumentValue(0, userSearchBase);
|
||||
search.getConstructorArgumentValues().addIndexedArgumentValue(1, userSearchFilter);
|
||||
search.getConstructorArgumentValues().addIndexedArgumentValue(2, parseServerReference(elt, parserContext));
|
||||
BeanDefinitionBuilder searchBuilder = BeanDefinitionBuilder.rootBeanDefinition(FilterBasedLdapUserSearch.class);
|
||||
searchBuilder.setSource(source);
|
||||
searchBuilder.addConstructorArg(userSearchBase);
|
||||
searchBuilder.addConstructorArg(userSearchFilter);
|
||||
searchBuilder.addConstructorArg(parseServerReference(elt, parserContext));
|
||||
|
||||
return search;
|
||||
return (RootBeanDefinition) searchBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
static RuntimeBeanReference parseServerReference(Element elt, ParserContext parserContext) {
|
||||
|
@ -87,7 +89,8 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||
String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
|
||||
String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
|
||||
String groupRoleAttribute = elt.getAttribute(ATT_GROUP_ROLE_ATTRIBUTE);
|
||||
|
||||
String rolePrefix = elt.getAttribute(ATT_ROLE_PREFIX);
|
||||
|
||||
if (!StringUtils.hasText(groupSearchFilter)) {
|
||||
groupSearchFilter = DEF_GROUP_SEARCH_FILTER;
|
||||
}
|
||||
|
@ -96,16 +99,23 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||
groupSearchBase = DEF_GROUP_SEARCH_BASE;
|
||||
}
|
||||
|
||||
RootBeanDefinition populator = new RootBeanDefinition(DefaultLdapAuthoritiesPopulator.class);
|
||||
BeanDefinitionBuilder populator = BeanDefinitionBuilder.rootBeanDefinition(DefaultLdapAuthoritiesPopulator.class);
|
||||
populator.setSource(parserContext.extractSource(elt));
|
||||
populator.getConstructorArgumentValues().addIndexedArgumentValue(0, parseServerReference(elt, parserContext));
|
||||
populator.getConstructorArgumentValues().addIndexedArgumentValue(1, groupSearchBase);
|
||||
populator.getPropertyValues().addPropertyValue("groupSearchFilter", groupSearchFilter);
|
||||
populator.addConstructorArg(parseServerReference(elt, parserContext));
|
||||
populator.addConstructorArg(groupSearchBase);
|
||||
populator.addPropertyValue("groupSearchFilter", groupSearchFilter);
|
||||
|
||||
if (StringUtils.hasText(rolePrefix)) {
|
||||
if ("none".equals(rolePrefix)) {
|
||||
rolePrefix = "";
|
||||
}
|
||||
populator.addPropertyValue("rolePrefix", rolePrefix);
|
||||
}
|
||||
|
||||
if (StringUtils.hasLength(groupRoleAttribute)) {
|
||||
populator.getPropertyValues().addPropertyValue("groupRoleAttribute", groupRoleAttribute);
|
||||
populator.addPropertyValue("groupRoleAttribute", groupRoleAttribute);
|
||||
}
|
||||
|
||||
return populator;
|
||||
return (RootBeanDefinition) populator.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,8 @@ ldap-us.attlist &=
|
|||
group-role-attribute-attribute?
|
||||
ldap-us.attlist &=
|
||||
cache-ref?
|
||||
|
||||
ldap-us.attlist &=
|
||||
role-prefix?
|
||||
|
||||
ldap-authentication-provider =
|
||||
## Sets up an ldap authentication provider
|
||||
|
@ -133,6 +134,8 @@ 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.
|
||||
attribute user-dn-pattern {xsd:string}?
|
||||
ldap-ap.attlist &=
|
||||
role-prefix?
|
||||
|
||||
password-compare-element =
|
||||
## Specifies that an LDAP provider should use an LDAP compare operation of the user's password to authenticate the user
|
||||
|
|
|
@ -297,6 +297,12 @@
|
|||
UserDetailsService.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</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:element name="ldap-authentication-provider">
|
||||
<xs:annotation>
|
||||
|
@ -383,6 +389,12 @@
|
|||
username.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</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 name="password-compare.attlist">
|
||||
<xs:attribute name="password-attribute" type="xs:string">
|
||||
|
|
|
@ -41,12 +41,15 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
|||
|
||||
Set authorities = AuthorityUtils.authorityArrayToSet(ben.getAuthorities());
|
||||
assertEquals(2, authorities.size());
|
||||
assertTrue(authorities.contains(new GrantedAuthorityImpl("ROLE_DEVELOPERS")));
|
||||
assertTrue(authorities.contains("ROLE_DEVELOPERS"));
|
||||
}
|
||||
|
||||
@Test
|
||||
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");
|
||||
UserDetails joe = uds.loadUserByUsername("Joe Smeth");
|
||||
|
@ -54,6 +57,27 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
|||
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
|
||||
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 />");
|
||||
|
|
Loading…
Reference in New Issue