diff --git a/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java
index e4458b0d32..e4628b6c05 100644
--- a/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java
@@ -4,7 +4,6 @@ import org.springframework.security.userdetails.jdbc.JdbcUserDetailsManager;
import org.springframework.util.StringUtils;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.w3c.dom.Element;
@@ -17,26 +16,30 @@ public class JdbcUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
static final String ATT_USERS_BY_USERNAME_QUERY = "users-by-username-query";
static final String ATT_AUTHORITIES_BY_USERNAME_QUERY = "authorities-by-username-query";
static final String ATT_GROUP_AUTHORITIES_QUERY = "group-authorities-by-username-query";
+ static final String ATT_ROLE_PREFIX = "role-prefix";
protected Class getBeanClass(Element element) {
return JdbcUserDetailsManager.class;
}
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
- // TODO: Set authenticationManager property
String dataSource = element.getAttribute(ATT_DATA_SOURCE);
- // An explicit dataSource was specified, so use it
+
if (dataSource != null) {
builder.addPropertyReference("dataSource", dataSource);
} else {
- // TODO: Have some sensible fallback if dataSource not specified, eg autowire
- throw new BeanDefinitionStoreException(ATT_DATA_SOURCE + " is required for "
- + Elements.JDBC_USER_SERVICE );
+ parserContext.getReaderContext().error(ATT_DATA_SOURCE + " is required for "
+ + Elements.JDBC_USER_SERVICE, parserContext.extractSource(element));
}
String usersQuery = element.getAttribute(ATT_USERS_BY_USERNAME_QUERY);
String authoritiesQuery = element.getAttribute(ATT_AUTHORITIES_BY_USERNAME_QUERY);
String groupAuthoritiesQuery = element.getAttribute(ATT_GROUP_AUTHORITIES_QUERY);
+ String rolePrefix = element.getAttribute(ATT_ROLE_PREFIX);
+
+ if (StringUtils.hasText(rolePrefix)) {
+ builder.addPropertyValue("rolePrefix", rolePrefix);
+ }
if (StringUtils.hasText(usersQuery)) {
builder.addPropertyValue("usersByUsernameQuery", usersQuery);
diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc
index 8c46dd6f72..005814ec01 100644
--- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc
+++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc
@@ -52,6 +52,10 @@ system-wide =
boolean = "true" | "false"
+role-prefix =
+ ## A non-empty string prefix that will be added to role strings loaded from persistent storage (e.g. "ROLE_").
+ attribute role-prefix {xsd:string}
+
ldap-server =
## Defines an LDAP server location or starts an embedded server. The url indicates the location of a remote server. If no url is given, an embedded server will be started, listening on the supplied port number. The port is optional and defaults to 33389. A Spring LDAP ContextSource bean will be registered for the server with the id supplied.
@@ -110,6 +114,7 @@ ldap-us.attlist &=
ldap-us.attlist &=
cache-ref?
+
ldap-authentication-provider =
## Sets up an ldap authentication provider
element ldap-authentication-provider {ldap-ap.attlist, password-compare-element?}
@@ -426,6 +431,8 @@ jdbc-user-service.attlist &=
jdbc-user-service.attlist &=
## An SQL statement to query user's group authorities given a username.
attribute group-authorities-by-username-query {xsd:string}?
+jdbc-user-service.attlist &=
+ role-prefix?
any-user-service = user-service | jdbc-user-service | ldap-user-service
diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd
index f1dd38fa30..cebce890ac 100644
--- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd
+++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd
@@ -150,6 +150,14 @@
+
+
+
+ A non-empty string prefix that will be added to role strings loaded from
+ persistent storage (e.g. "ROLE_").
+
+
+
Defines an LDAP server location or starts an embedded server. The url
@@ -1168,6 +1176,12 @@
username.
+
+
+ A non-empty string prefix that will be added to role strings loaded from
+ persistent storage (e.g. "ROLE_").
+
+
diff --git a/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java
index 789435ed75..57b1f2d79d 100644
--- a/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java
+++ b/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java
@@ -10,7 +10,9 @@ import org.springframework.security.AuthenticationManager;
import org.springframework.security.providers.ProviderManager;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.dao.DaoAuthenticationProvider;
+import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.jdbc.JdbcUserDetailsManager;
+import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.util.InMemoryXmlApplicationContext;
/**
@@ -61,7 +63,7 @@ public class JdbcUserServiceBeanDefinitionParserTests {
JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext.getBean("myUserService");
assertTrue(mgr.loadUserByUsername("rod") != null);
}
-
+
@Test
public void cacheRefIsparsedCorrectly() {
setContext(""
@@ -94,6 +96,15 @@ public class JdbcUserServiceBeanDefinitionParserTests {
provider.authenticate(new UsernamePasswordAuthenticationToken("rod","koala"));
assertNotNull("Cache should contain user after authentication", provider.getUserCache().getUserFromCache("rod"));
}
+
+ @Test
+ public void rolePrefixIsUsedWhenSet() {
+ setContext("" + DATA_SOURCE);
+ JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext.getBean("myUserService");
+ UserDetails rod = mgr.loadUserByUsername("rod");
+ assertTrue(AuthorityUtils.authorityArrayToSet(rod.getAuthorities()).contains("PREFIX_ROLE_SUPERVISOR"));
+ }
+
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);