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

This commit is contained in:
Luke Taylor 2008-12-17 01:11:43 +00:00
parent 00125cddee
commit 171456a26c
5 changed files with 49 additions and 28 deletions

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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}

View File

@ -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>

View File

@ -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'/>" +