소스 검색

SEC-1352: Added support for placeholders in <user-service>

The username, password and authorities attributes can now be placeholders.
Luke Taylor 15 년 전
부모
커밋
dc5417f1d5

+ 27 - 13
config/src/main/java/org/springframework/security/config/authentication/UserServiceBeanDefinitionParser.java

@@ -1,28 +1,28 @@
 package org.springframework.security.config.authentication;
 
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Iterator;
+import java.util.List;
+
+import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.config.PropertiesFactoryBean;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedMap;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.memory.UserMap;
-import org.springframework.util.StringUtils;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import org.springframework.util.xml.DomUtils;
 import org.w3c.dom.Element;
 
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.List;
-import java.util.Iterator;
-
 /**
  * @author Luke Taylor
  * @author Ben Alex
- * @version $Id$
  */
 public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceBeanDefinitionParser {
 
@@ -63,7 +63,8 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
                 "properties file (using the '" + ATT_PROPERTIES + "' attribute)" );
         }
 
-        UserMap users = new UserMap();
+        BeanDefinition userMap = new RootBeanDefinition(UserMap.class);
+        ManagedMap<String, BeanDefinition> users = new ManagedMap<String, BeanDefinition>();
 
         for (Iterator i = userElts.iterator(); i.hasNext();) {
             Element userElt = (Element) i.next();
@@ -76,12 +77,25 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
 
             boolean locked = "true".equals(userElt.getAttribute(ATT_LOCKED));
             boolean disabled = "true".equals(userElt.getAttribute(ATT_DISABLED));
-
-            users.addUser(new User(userName, password, !disabled, true, true, !locked,
-                    AuthorityUtils.commaSeparatedStringToAuthorityList(userElt.getAttribute(ATT_AUTHORITIES))));
+            BeanDefinitionBuilder authorities = BeanDefinitionBuilder.rootBeanDefinition(AuthorityUtils.class);
+            authorities.addConstructorArgValue(userElt.getAttribute(ATT_AUTHORITIES));
+            authorities.setFactoryMethod("commaSeparatedStringToAuthorityList");
+
+            BeanDefinitionBuilder user = BeanDefinitionBuilder.rootBeanDefinition(User.class);
+            user.addConstructorArgValue(userName);
+            user.addConstructorArgValue(password);
+            user.addConstructorArgValue(!disabled);
+            user.addConstructorArgValue(true);
+            user.addConstructorArgValue(true);
+            user.addConstructorArgValue(!locked);
+            user.addConstructorArgValue(authorities.getBeanDefinition());
+
+            users.put(userName, user.getBeanDefinition());
         }
 
-        builder.addPropertyValue("userMap", users);
+        userMap.getPropertyValues().addPropertyValue("users", users);
+
+        builder.addPropertyValue("userMap", userMap);
     }
 
     private String generateRandomPassword() {

+ 16 - 1
config/src/test/java/org/springframework/security/config/authentication/UserServiceBeanDefinitionParserTests.java

@@ -13,7 +13,6 @@ import org.junit.After;
 
 /**
  * @author Luke Taylor
- * @version $Id$
  */
 public class UserServiceBeanDefinitionParserTests {
     private AbstractXmlApplicationContext appContext;
@@ -45,6 +44,22 @@ public class UserServiceBeanDefinitionParserTests {
         userService.loadUserByUsername("joe");
     }
 
+    @Test
+    public void namePasswordAndAuthoritiesSupportPlaceholders() {
+        System.setProperty("principal.name", "joe");
+        System.setProperty("principal.pass", "joespassword");
+        System.setProperty("principal.authorities", "ROLE_A,ROLE_B");
+        setContext(
+                "<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +
+                "<user-service id='service'>" +
+                "    <user name='${principal.name}' password='${principal.pass}' authorities='${principal.authorities}'/>" +
+                "</user-service>");
+        UserDetailsService userService = (UserDetailsService) appContext.getBean("service");
+        UserDetails joe = userService.loadUserByUsername("joe");
+        assertEquals("joespassword", joe.getPassword());
+        assertEquals(2, joe.getAuthorities().size());
+    }
+
     @Test
     public void embeddedUsersWithNoPasswordIsGivenGeneratedValue() {
         setContext(