浏览代码

SEC-1018: Changes to allow external reference to SaltSource bean from the namespace.

Luke Taylor 16 年之前
父节点
当前提交
171456a26c

+ 13 - 15
core/src/main/java/org/springframework/security/config/PasswordEncoderParser.java

@@ -1,26 +1,24 @@
 package org.springframework.security.config;
 
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.security.providers.encoding.BaseDigestPasswordEncoder;
 import org.springframework.security.providers.encoding.Md4PasswordEncoder;
 import org.springframework.security.providers.encoding.Md5PasswordEncoder;
 import org.springframework.security.providers.encoding.PasswordEncoder;
 import org.springframework.security.providers.encoding.PlaintextPasswordEncoder;
 import org.springframework.security.providers.encoding.ShaPasswordEncoder;
-import org.springframework.security.providers.encoding.BaseDigestPasswordEncoder;
 import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.beans.BeanMetadataElement;
 import org.springframework.util.StringUtils;
 import org.springframework.util.xml.DomUtils;
-
 import org.w3c.dom.Element;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.Map;
-import java.util.HashMap;
 
 /**
  * Stateful parser for the <password-encoder> element.
@@ -30,7 +28,7 @@ import java.util.HashMap;
  * @author Luke Taylor
  * @version $Id$
  */
-public class PasswordEncoderParser {
+class PasswordEncoderParser {
     static final String ATT_REF = "ref";
     static final String ATT_HASH = "hash";
     static final String ATT_BASE_64 = "base64";
@@ -56,7 +54,7 @@ public class PasswordEncoderParser {
     private Log logger = LogFactory.getLog(getClass());
 
     private BeanMetadataElement passwordEncoder;
-    private BeanDefinition saltSource;
+    private BeanMetadataElement saltSource;
 
     public PasswordEncoderParser(Element element, ParserContext parserContext) {
         parse(element, parserContext);
@@ -104,7 +102,7 @@ public class PasswordEncoderParser {
         return passwordEncoder;
     }
 
-    public BeanDefinition getSaltSource() {
+    public BeanMetadataElement getSaltSource() {
         return saltSource;
     }
 }

+ 15 - 7
core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java

@@ -1,8 +1,9 @@
 package org.springframework.security.config;
 
+import org.springframework.beans.BeanMetadataElement;
 import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.springframework.security.providers.dao.salt.ReflectionSaltSource;
 import org.springframework.security.providers.dao.salt.SystemWideSaltSource;
@@ -14,20 +15,27 @@ import org.w3c.dom.Element;
  * @version $Id$
  * @since 2.0
  */
-public class SaltSourceBeanDefinitionParser implements BeanDefinitionParser {
-    static final String ATT_USER_PROPERTY = "user-property";
-    static final String ATT_SYSTEM_WIDE = "system-wide";
+class SaltSourceBeanDefinitionParser {
+    private static final String ATT_USER_PROPERTY = "user-property";
+    private static final String ATT_REF = "ref";
+    private static final String ATT_SYSTEM_WIDE = "system-wide";
+
+    public BeanMetadataElement parse(Element element, ParserContext parserContext) {
+        String ref = element.getAttribute(ATT_REF);
+
+        if (StringUtils.hasText(ref)) {
+            return new RuntimeBeanReference(ref);
+        }
 
-    public BeanDefinition parse(Element element, ParserContext parserContext) {
-        RootBeanDefinition saltSource;
         String userProperty = element.getAttribute(ATT_USER_PROPERTY);
+        RootBeanDefinition saltSource;
 
         if (StringUtils.hasText(userProperty)) {
             saltSource = new RootBeanDefinition(ReflectionSaltSource.class);
             saltSource.getPropertyValues().addPropertyValue("userPropertyToUse", userProperty);
             saltSource.setSource(parserContext.extractSource(element));
             saltSource.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-            
+
             return saltSource;
         }
 

+ 1 - 1
core/src/main/resources/org/springframework/security/config/spring-security-2.5.rnc

@@ -47,7 +47,7 @@ password-encoder.attlist &=
     
 salt-source =
     ## Password salting strategy. A system-wide constant or a property from the UserDetails object can be used.
-    element salt-source {user-property | system-wide}
+    element salt-source {user-property | system-wide | ref}
 user-property =
     ## A property of the UserDetails object which will be used as salt by a password encoder. Typically something like "username" might be used. 
     attribute user-property {xsd:string}

+ 12 - 0
core/src/main/resources/org/springframework/security/config/spring-security-2.5.xsd

@@ -419,6 +419,12 @@
                                              salt for a password encoder. </xs:documentation>
                                        </xs:annotation>
                                     </xs:attribute>
+                                    <xs:attribute name="ref" type="xs:string">
+                                       <xs:annotation>
+                                          <xs:documentation>Defines a reference to a Spring bean
+                                             Id.</xs:documentation>
+                                       </xs:annotation>
+                                    </xs:attribute>
                                  </xs:complexType>
                               </xs:element>
                            </xs:sequence>
@@ -1331,6 +1337,12 @@
                                     a password encoder. </xs:documentation>
                               </xs:annotation>
                            </xs:attribute>
+                           <xs:attribute name="ref" type="xs:string">
+                              <xs:annotation>
+                                 <xs:documentation>Defines a reference to a Spring bean
+                                    Id.</xs:documentation>
+                              </xs:annotation>
+                           </xs:attribute>
                         </xs:complexType>
                      </xs:element>
                   </xs:sequence>

+ 8 - 5
core/src/test/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParserTests.java

@@ -87,7 +87,7 @@ public class AuthenticationProviderBeanDefinitionParserTests {
         ShaPasswordEncoder encoder = (ShaPasswordEncoder) FieldUtils.getFieldValue(getProvider(), "passwordEncoder");
         assertEquals("SHA-256", encoder.getAlgorithm());
     }
-    
+
     @Test
     public void passwordIsBase64EncodedWhenBase64IsEnabled() throws Exception {
         setContext(" <authentication-provider>" +
@@ -99,18 +99,21 @@ public class AuthenticationProviderBeanDefinitionParserTests {
 
         getProvider().authenticate(bob);
     }
-    
+
     @Test
-    public void externalUserServiceAndPasswordEncoderWork() throws Exception {
+    public void externalUserServicePasswordEncoderAndSaltSourceWork() throws Exception {
         setContext(" <authentication-provider user-service-ref='customUserService'>" +
                 "        <password-encoder ref='customPasswordEncoder'>" +
-                "            <salt-source user-property='username'/>" +
+                "            <salt-source ref='saltSource'/>" +
                 "        </password-encoder>" +
                 "    </authentication-provider>" +
 
                 "    <b:bean id='customPasswordEncoder' " +
                             "class='org.springframework.security.providers.encoding.Md5PasswordEncoder'/>" +
-
+                "    <b:bean id='saltSource' " +
+                "           class='org.springframework.security.providers.dao.salt.ReflectionSaltSource'>" +
+                "         <b:property name='userPropertyToUse' value='username'/>" +
+                "    </b:bean>" +
                 "    <b:bean id='customUserService' " +
                 "           class='org.springframework.security.userdetails.memory.InMemoryDaoImpl'>" +
                 "        <b:property name='userMap' value='bob=f117f0862384e9497ff4f470e3522606,ROLE_A'/>" +