SEC-1331: Modify namespace to allow omission of user passwords in user-service element and generate random ones internally, preventing authentication against the data..

This commit is contained in:
Luke Taylor 2009-12-18 15:39:13 +00:00
parent fabe03ba33
commit 85a58fd473
5 changed files with 45 additions and 12 deletions

View File

@ -14,6 +14,8 @@ import org.springframework.util.CollectionUtils;
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;
@ -32,6 +34,8 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
static final String ATT_DISABLED = "disabled";
static final String ATT_LOCKED = "locked";
private SecureRandom random;
protected String getBeanClassName(Element element) {
return "org.springframework.security.core.userdetails.memory.InMemoryDaoImpl";
}
@ -65,6 +69,11 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
Element userElt = (Element) i.next();
String userName = userElt.getAttribute(ATT_NAME);
String password = userElt.getAttribute(ATT_PASSWORD);
if (!StringUtils.hasLength(password)) {
password = generateRandomPassword();
}
boolean locked = "true".equals(userElt.getAttribute(ATT_LOCKED));
boolean disabled = "true".equals(userElt.getAttribute(ATT_DISABLED));
@ -74,4 +83,16 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
builder.addPropertyValue("userMap", users);
}
private String generateRandomPassword() {
if (random == null) {
try {
random = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
// Shouldn't happen...
throw new RuntimeException("Failed find SHA1PRNG algorithm!");
}
}
return Long.toString(random.nextLong());
}
}

View File

@ -533,7 +533,7 @@ x509.attlist &=
user-service-ref?
authentication-manager =
## Registers the AuthenticationManager instance and allows its list of AuthenticationProviders to be defined. should use. Also allows you to define an alias to allow you to reference the AuthenticationManager in your own beans.
## Registers the AuthenticationManager instance and allows its list of AuthenticationProviders to be defined. Also allows you to define an alias to allow you to reference the AuthenticationManager in your own beans.
element authentication-manager {authman.attlist & authentication-provider* & ldap-authentication-provider*}
authman.attlist &=
## The alias you wish to use for the AuthenticationManager bean
@ -562,8 +562,8 @@ user.attlist &=
## The username assigned to the user.
attribute name {xsd:token}
user.attlist &=
## The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element).
attribute password {xsd:string}
## The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element). This attribute be omitted in the case where the data will not be used for authentication, but only for accessing authorities. If omitted, the namespace will generate a random value, preventing its accidental use for authentication. Cannot be empty.
attribute password {xsd:string}?
user.attlist &=
## One of more authorities granted to the user. Separate authorities with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR"
attribute authorities {xsd:token}

View File

@ -1096,7 +1096,7 @@
</xs:attribute>
</xs:attributeGroup>
<xs:element name="authentication-manager"><xs:annotation>
<xs:documentation>Registers the AuthenticationManager instance and allows its list of AuthenticationProviders to be defined. should use. Also allows you to define an alias to allow you to reference the AuthenticationManager in your own beans. </xs:documentation>
<xs:documentation>Registers the AuthenticationManager instance and allows its list of AuthenticationProviders to be defined. Also allows you to define an alias to allow you to reference the AuthenticationManager in your own beans. </xs:documentation>
</xs:annotation><xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="authentication-provider"><xs:annotation>
@ -1223,9 +1223,9 @@
<xs:documentation>The username assigned to the user.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" use="required" type="xs:string">
<xs:attribute name="password" type="xs:string">
<xs:annotation>
<xs:documentation>The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element).</xs:documentation>
<xs:documentation>The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element). This attribute be omitted in the case where the data will not be used for authentication, but only for accessing authorities. If omitted, the namespace will generate a random value, preventing its accidental use for authentication. Cannot be empty.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="authorities" use="required" type="xs:token">

View File

@ -45,6 +45,18 @@ public class UserServiceBeanDefinitionParserTests {
userService.loadUserByUsername("joe");
}
@Test
public void embeddedUsersWithNoPasswordIsGivenGeneratedValue() {
setContext(
"<user-service id='service'>" +
" <user name='joe' authorities='ROLE_A'/>" +
"</user-service>");
UserDetailsService userService = (UserDetailsService) appContext.getBean("service");
UserDetails joe = userService.loadUserByUsername("joe");
assertTrue(joe.getPassword().length() > 0);
Long.parseLong(joe.getPassword());
}
@Test
public void disabledAndEmbeddedFlagsAreSupported() {
setContext(

View File

@ -27,10 +27,10 @@
<authentication-manager alias="authenticationManager"/>
<user-service id="userService">
<user name="http://luke.taylor.myopenid.com/" password="notused" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://luke.taylor.openid.cn/" password="notused" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://raykrueger.blogspot.com/" password="notused" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://spring.security.test.myopenid.com/" password="password" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://luke.taylor.myopenid.com/" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://luke.taylor.openid.cn/" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://raykrueger.blogspot.com/" authorities="ROLE_SUPERVISOR,ROLE_USER" />
<user name="http://spring.security.test.myopenid.com/" authorities="ROLE_SUPERVISOR,ROLE_USER" />
</user-service>
</b:beans>