diff --git a/core/src/main/java/org/springframework/security/config/PasswordEncoderParser.java b/core/src/main/java/org/springframework/security/config/PasswordEncoderParser.java index 5f9b2ef8cc..8f48110345 100644 --- a/core/src/main/java/org/springframework/security/config/PasswordEncoderParser.java +++ b/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 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; } } diff --git a/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java index 8f33108bfc..40ebe9508e 100644 --- a/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java +++ b/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; } diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.5.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.5.rnc index 153fefab76..f524dc7284 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.5.rnc +++ b/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} diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.5.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.5.xsd index 5f4841e5ae..4a52d45f74 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.5.xsd +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.5.xsd @@ -419,6 +419,12 @@ salt for a password encoder. + + + Defines a reference to a Spring bean + Id. + + @@ -1331,6 +1337,12 @@ a password encoder. + + + Defines a reference to a Spring bean + Id. + + diff --git a/core/src/test/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParserTests.java index cfb1bb09c6..99219beff1 100644 --- a/core/src/test/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParserTests.java +++ b/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(" " + @@ -99,18 +99,21 @@ public class AuthenticationProviderBeanDefinitionParserTests { getProvider().authenticate(bob); } - + @Test - public void externalUserServiceAndPasswordEncoderWork() throws Exception { + public void externalUserServicePasswordEncoderAndSaltSourceWork() throws Exception { setContext(" " + " " + - " " + + " " + " " + " " + " " + - + " " + + " " + + " " + " " + " " +