From 9eaa1cbbdd82eb85ac196f5d071415f7a9915324 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Mon, 21 Apr 2008 18:29:54 +0000 Subject: [PATCH] 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. --- .../LdapUserServiceBeanDefinitionParser.java | 36 ++++++++++++------- .../security/config/spring-security-2.0.rnc | 5 ++- .../security/config/spring-security-2.0.xsd | 12 +++++++ ...pUserServiceBeanDefinitionParserTests.java | 28 +++++++++++++-- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParser.java index 54f8734980..32e842db9c 100644 --- a/core/src/main/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParser.java @@ -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(); } } diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc index 005814ec01..e4bfba0659 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc @@ -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 diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd index cebce890ac..d6d76bdcb5 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd @@ -297,6 +297,12 @@ UserDetailsService. + + + A non-empty string prefix that will be added to role strings loaded from + persistent storage (e.g. "ROLE_"). + + @@ -383,6 +389,12 @@ username. + + + A non-empty string prefix that will be added to role strings loaded from + persistent storage (e.g. "ROLE_"). + + diff --git a/core/src/test/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParserTests.java index 196612c2b1..3221044d51 100644 --- a/core/src/test/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParserTests.java +++ b/core/src/test/java/org/springframework/security/config/LdapUserServiceBeanDefinitionParserTests.java @@ -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(""); + setContext(""); 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( + "" + + ""); + + 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("");