diff --git a/core/src/main/java/org/springframework/security/config/AbstractUserDetailsServiceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/AbstractUserDetailsServiceBeanDefinitionParser.java
index 471215f99a..4b1df14ce5 100644
--- a/core/src/main/java/org/springframework/security/config/AbstractUserDetailsServiceBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/AbstractUserDetailsServiceBeanDefinitionParser.java
@@ -1,8 +1,12 @@
package org.springframework.security.config;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
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.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.util.StringUtils;
@@ -12,16 +16,53 @@ import org.w3c.dom.Element;
* @author Luke Taylor
* @version $Id$
*/
-public class AbstractUserDetailsServiceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
+public abstract class AbstractUserDetailsServiceBeanDefinitionParser implements BeanDefinitionParser {
+ private static final String CACHE_REF = "cache-ref";
+ public static final String CACHING_SUFFIX = ".caching";
+
+ /** UserDetailsService bean Id. For use in a stateful context (i.e. in AuthenticationProviderBDP) */
+ private String id;
+
+ protected abstract Class getBeanClass(Element element);
+
+ protected abstract void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);
+
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClass(element));
+
+ doParse(element, parserContext, builder);
+
+ RootBeanDefinition userService = (RootBeanDefinition) builder.getBeanDefinition();
+ String beanId = resolveId(element, userService, parserContext);
+
+ parserContext.getRegistry().registerBeanDefinition(beanId, userService);
+
+ String cacheRef = element.getAttribute(CACHE_REF);
+
+ // Register a caching version of the user service if there's a cache-ref
+ if (StringUtils.hasText(cacheRef)) {
+ BeanDefinitionBuilder cachingUSBuilder = BeanDefinitionBuilder.rootBeanDefinition(CachingUserDetailsService.class);
+ cachingUSBuilder.addConstructorArgReference(beanId);
+
+ cachingUSBuilder.addPropertyValue("userCache", new RuntimeBeanReference(cacheRef));
+ BeanDefinition cachingUserService = cachingUSBuilder.getBeanDefinition();
+ parserContext.getRegistry().registerBeanDefinition(beanId + CACHING_SUFFIX, cachingUserService);
+ }
- protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
- String id = super.resolveId(element, definition, parserContext);
+ id = beanId;
+
+ return null;
+ }
+
+ private String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
+ throws BeanDefinitionStoreException {
+
+ String id = element.getAttribute("id");
if (StringUtils.hasText(id)) {
return id;
}
- // If it's nested in a parent auth-provider, generate an id automatically
if(Elements.AUTHENTICATION_PROVIDER.equals(element.getParentNode().getNodeName())) {
return parserContext.getReaderContext().generateBeanName(definition);
}
@@ -34,4 +75,8 @@ public class AbstractUserDetailsServiceBeanDefinitionParser extends AbstractSing
return BeanIds.USER_DETAILS_SERVICE;
}
+
+ String getId() {
+ return id;
+ }
}
diff --git a/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java
index c4cc2c5e3a..eff2625249 100644
--- a/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java
@@ -1,14 +1,19 @@
package org.springframework.security.config;
-import org.springframework.security.providers.dao.DaoAuthenticationProvider;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.util.xml.DomUtils;
+import org.springframework.core.Ordered;
+import org.springframework.security.providers.dao.DaoAuthenticationProvider;
import org.springframework.util.StringUtils;
-
+import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
@@ -36,40 +41,88 @@ class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser
}
}
- ConfigUtils.getRegisteredProviders(parserContext).add(authProvider);
-
- String ref = element.getAttribute(ATT_USER_DETAILS_REF);
Element userServiceElt = DomUtils.getChildElementByTagName(element, Elements.USER_SERVICE);
Element jdbcUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE);
Element ldapUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.LDAP_USER_SERVICE);
- if (StringUtils.hasText(ref)) {
+ // We need to register the provider to access it in the post processor to check if it has a cache
+ final String id = parserContext.getReaderContext().generateBeanName(authProvider);
+ parserContext.getRegistry().registerBeanDefinition(id, authProvider);
+
+ String ref = element.getAttribute(ATT_USER_DETAILS_REF);
+
+ if (StringUtils.hasText(ref)) {
if (userServiceElt != null || jdbcUserServiceElt != null || ldapUserServiceElt != null) {
- parserContext.getReaderContext().error("The ref attribute cannot be used in combination with child" +
+ parserContext.getReaderContext().error("The " + ATT_USER_DETAILS_REF + " attribute cannot be used in combination with child" +
"elements '" + Elements.USER_SERVICE + "', '" + Elements.JDBC_USER_SERVICE + "' or '" +
Elements.LDAP_USER_SERVICE + "'", element);
}
-
- authProvider.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(ref));
-
- return null;
- }
-
- // Use the child elements to create the UserDetailsService
- BeanDefinition userDetailsService = null;
-
- if (userServiceElt != null) {
- userDetailsService = new UserServiceBeanDefinitionParser().parse(userServiceElt, parserContext);
- } else if (jdbcUserServiceElt != null) {
- userDetailsService = new JdbcUserServiceBeanDefinitionParser().parse(jdbcUserServiceElt, parserContext);
- } else if (ldapUserServiceElt != null) {
- userDetailsService = new LdapUserServiceBeanDefinitionParser().parse(ldapUserServiceElt, parserContext);
} else {
- parserContext.getReaderContext().error("A user-service is required", element);
+ // Use the child elements to create the UserDetailsService
+ AbstractUserDetailsServiceBeanDefinitionParser parser = null;
+ Element elt = null;
+
+ if (userServiceElt != null) {
+ elt = userServiceElt;
+ parser = new UserServiceBeanDefinitionParser();
+ } else if (jdbcUserServiceElt != null) {
+ elt = jdbcUserServiceElt;
+ parser = new JdbcUserServiceBeanDefinitionParser();
+ } else if (ldapUserServiceElt != null) {
+ elt = ldapUserServiceElt;
+ parser = new LdapUserServiceBeanDefinitionParser();
+ } else {
+ parserContext.getReaderContext().error("A user-service is required", element);
+ }
+
+ parser.parse(elt, parserContext);
+ ref = parser.getId();
}
+
+ authProvider.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(ref));
- authProvider.getPropertyValues().addPropertyValue("userDetailsService", userDetailsService);
+ BeanDefinitionBuilder cacheResolverBldr = BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProviderCacheResolver.class);
+ cacheResolverBldr.addConstructorArg(id);
+ cacheResolverBldr.addConstructorArg(ref);
+ cacheResolverBldr.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ BeanDefinition cacheResolver = cacheResolverBldr.getBeanDefinition();
+ parserContext.getRegistry().registerBeanDefinition(
+ parserContext.getReaderContext().generateBeanName(cacheResolver), cacheResolver);
+ ConfigUtils.getRegisteredProviders(parserContext).add(new RuntimeBeanReference(id));
+
return null;
}
+
+ /**
+ * Checks whether the registered user service bean has an associated cache and, if so, sets it on the
+ * authentication provider.
+ */
+ static class AuthenticationProviderCacheResolver implements BeanFactoryPostProcessor, Ordered {
+ private String providerId;
+ private String userServiceId;
+
+ public AuthenticationProviderCacheResolver(String providerId, String userServiceId) {
+ this.providerId = providerId;
+ this.userServiceId = userServiceId;
+ }
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ RootBeanDefinition provider = (RootBeanDefinition) beanFactory.getBeanDefinition(providerId);
+
+ String cachingId = userServiceId + AbstractUserDetailsServiceBeanDefinitionParser.CACHING_SUFFIX;
+
+ if (beanFactory.containsBeanDefinition(cachingId)) {
+ RootBeanDefinition cachingUserService = (RootBeanDefinition) beanFactory.getBeanDefinition(cachingId);
+
+ PropertyValue userCacheProperty = cachingUserService.getPropertyValues().getPropertyValue("userCache");
+
+ provider.getPropertyValues().addPropertyValue(userCacheProperty);
+ }
+ }
+
+ public int getOrder() {
+ return HIGHEST_PRECEDENCE;
+ }
+ }
}
diff --git a/core/src/main/java/org/springframework/security/config/CachingUserDetailsService.java b/core/src/main/java/org/springframework/security/config/CachingUserDetailsService.java
new file mode 100644
index 0000000000..505e3ada79
--- /dev/null
+++ b/core/src/main/java/org/springframework/security/config/CachingUserDetailsService.java
@@ -0,0 +1,44 @@
+package org.springframework.security.config;
+
+import org.springframework.security.providers.dao.UserCache;
+import org.springframework.security.providers.dao.cache.NullUserCache;
+import org.springframework.security.userdetails.UserDetailsService;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.util.Assert;
+
+/**
+ *
+ * @author Luke Taylor
+ * @since 2.0
+ */
+class CachingUserDetailsService implements UserDetailsService {
+ private UserCache userCache = new NullUserCache();
+ private UserDetailsService delegate;
+
+ CachingUserDetailsService(UserDetailsService delegate) {
+ this.delegate = delegate;
+ }
+
+ public UserCache getUserCache() {
+ return userCache;
+ }
+
+ public void setUserCache(UserCache userCache) {
+ this.userCache = userCache;
+ }
+
+ public UserDetails loadUserByUsername(String username) {
+ UserDetails user = userCache.getUserFromCache(username);
+
+ if (user == null) {
+ user = delegate.loadUserByUsername(username);
+ }
+
+ Assert.notNull(user, "UserDetailsService " + delegate + " returned null for username " + username + ". " +
+ "This is an interface contract violation");
+
+ userCache.putUserInCache(user);
+
+ return user;
+ }
+}
diff --git a/core/src/main/java/org/springframework/security/config/ConfigUtils.java b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
index 4a784e5951..8d5ed9d1f0 100644
--- a/core/src/main/java/org/springframework/security/config/ConfigUtils.java
+++ b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
@@ -74,8 +74,16 @@ public abstract class ConfigUtils {
}
+ /**
+ * Obtains a user details service for use in RememberMeServices etc. Will return a caching version
+ * if available so should not be used for beans which need to separate the two.
+ */
static UserDetailsService getUserDetailsService(ConfigurableListableBeanFactory bf) {
- Map services = bf.getBeansOfType(UserDetailsService.class);
+ Map services = bf.getBeansOfType(CachingUserDetailsService.class);
+
+ if (services.size() == 0) {
+ services = bf.getBeansOfType(UserDetailsService.class);
+ }
if (services.size() == 0) {
throw new IllegalArgumentException("No UserDetailsService registered.");
diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
index 81fae79468..f886c21cf5 100644
--- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
@@ -260,7 +260,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
registry.registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, filterSecurityInterceptorBuilder.getBeanDefinition());
// Register the post processor which will tie up the loose ends in the configuration once the app context has been created and all beans are available.
- registry.registerBeanDefinition(BeanIds.HTTP_POST_PROCESSOR, new RootBeanDefinition(HttpSecurityConfigPostProcessor.class));
+ RootBeanDefinition postProcessor = new RootBeanDefinition(HttpSecurityConfigPostProcessor.class);
+ postProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ registry.registerBeanDefinition(BeanIds.HTTP_POST_PROCESSOR, postProcessor);
return null;
}
diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
index 3d0d0a86b7..03a6aaeb10 100644
--- a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
+++ b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java
@@ -16,6 +16,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.security.concurrent.ConcurrentSessionFilter;
@@ -52,30 +54,46 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
configureFilterChain(beanFactory);
}
- private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory beanFactory) {
+ private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory bf) {
try {
- BeanDefinition rememberMeServices = beanFactory.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES);
+ BeanDefinition rememberMeServices = bf.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES);
PropertyValue pv = rememberMeServices.getPropertyValues().getPropertyValue("userDetailsService");
if (pv == null) {
rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService",
- ConfigUtils.getUserDetailsService(beanFactory));
+ ConfigUtils.getUserDetailsService(bf));
+ } else {
+ RuntimeBeanReference cachingUserService = getCachingUserService(bf, pv.getValue());
+
+ if (cachingUserService != null) {
+ rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService", cachingUserService);
+ }
}
} catch (NoSuchBeanDefinitionException e) {
// ignore
}
}
- private void injectUserDetailsServiceIntoX509Provider(ConfigurableListableBeanFactory beanFactory) {
+ private void injectUserDetailsServiceIntoX509Provider(ConfigurableListableBeanFactory bf) {
try {
- BeanDefinition x509AuthProvider = beanFactory.getBeanDefinition(BeanIds.X509_AUTH_PROVIDER);
+ BeanDefinition x509AuthProvider = bf.getBeanDefinition(BeanIds.X509_AUTH_PROVIDER);
PropertyValue pv = x509AuthProvider.getPropertyValues().getPropertyValue("preAuthenticatedUserDetailsService");
if (pv == null) {
UserDetailsByNameServiceWrapper preAuthUserService = new UserDetailsByNameServiceWrapper();
- preAuthUserService.setUserDetailsService(ConfigUtils.getUserDetailsService(beanFactory));
+ preAuthUserService.setUserDetailsService(ConfigUtils.getUserDetailsService(bf));
x509AuthProvider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService",
preAuthUserService);
+ } else {
+ RootBeanDefinition preAuthUserService = (RootBeanDefinition) pv.getValue();
+ Object userService =
+ preAuthUserService.getPropertyValues().getPropertyValue("userDetailsService").getValue();
+
+ RuntimeBeanReference cachingUserService = getCachingUserService(bf, userService);
+
+ if (cachingUserService != null) {
+ preAuthUserService.getPropertyValues().addPropertyValue("userDetailsService", cachingUserService);
+ }
}
} catch (NoSuchBeanDefinitionException e) {
// ignore
@@ -94,7 +112,22 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
} catch (NoSuchBeanDefinitionException e) {
// ignore
}
- }
+ }
+
+ private RuntimeBeanReference getCachingUserService(ConfigurableListableBeanFactory bf, Object userServiceRef) {
+ Assert.isInstanceOf(RuntimeBeanReference.class, userServiceRef,
+ "userDetailsService property value must be a RuntimeBeanReference");
+
+ String id = ((RuntimeBeanReference)userServiceRef).getBeanName();
+ // Overwrite with the caching version if available
+ String cachingId = id + AbstractUserDetailsServiceBeanDefinitionParser.CACHING_SUFFIX;
+
+ if (bf.containsBeanDefinition(cachingId)) {
+ return new RuntimeBeanReference(cachingId);
+ }
+
+ return null;
+ }
/**
* Sets the authentication manager, (and remember-me services, if required) on any instances of
@@ -148,7 +181,7 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
*
* - If only one, use that one.
* - If more than one, use the form login entry point (if form login is being used), then try basic
- * - If still null, throw an exception (for now). TODO: Examine additional beans and types and make decision
+ * - If still null, throw an exception (for now).
*
*
*/
@@ -257,6 +290,6 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
}
public int getOrder() {
- return HIGHEST_PRECEDENCE;
+ return HIGHEST_PRECEDENCE + 1;
}
}
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 fc7077f6f6..b0f17a9bb7 100644
--- a/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParser.java
@@ -2,6 +2,7 @@ package org.springframework.security.config;
import org.springframework.security.userdetails.jdbc.JdbcUserDetailsManager;
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,7 +18,7 @@ public class JdbcUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
return JdbcUserDetailsManager.class;
}
- protected void doParse(Element element, BeanDefinitionBuilder builder) {
+ 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
diff --git a/core/src/main/java/org/springframework/security/config/UserServiceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/UserServiceBeanDefinitionParser.java
index fc1198db45..743489a1b1 100644
--- a/core/src/main/java/org/springframework/security/config/UserServiceBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/UserServiceBeanDefinitionParser.java
@@ -4,6 +4,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.security.userdetails.memory.InMemoryDaoImpl;
import org.springframework.security.userdetails.memory.UserMap;
@@ -36,7 +37,7 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
return InMemoryDaoImpl.class;
}
- protected void doParse(Element element, BeanDefinitionBuilder builder) {
+ protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String userProperties = element.getAttribute(ATT_PROPERTIES);
List userElts = DomUtils.getChildElementsByTagName(element, ELT_USER);
diff --git a/core/src/main/java/org/springframework/security/providers/UserDetailsService.java b/core/src/main/java/org/springframework/security/providers/UserDetailsService.java
deleted file mode 100644
index 62d6020b7d..0000000000
--- a/core/src/main/java/org/springframework/security/providers/UserDetailsService.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.providers;
-
-import org.springframework.security.AuthenticationException;
-import org.springframework.security.userdetails.UserDetails;
-
-/**
- * Populates the UserDetails
associated with a CAS authenticated
- * user.
- *
- *
- * Intended to grant authorities (roles) for providers that do not support
- * authorities/roles directly. It merely authenticates their identity.
- * As Spring Security needs to know the authorities granted to a user in
- * order to construct a valid Authentication
object, implementations
- * of this interface will provide this information.
- *
- *
- *
- * A {@link UserDetails} is returned by implementations. The
- * UserDetails
must, at minimum, contain the username and
- * GrantedAuthority[]
objects applicable to the authenticated
- * user. Note that Spring Security ignores the password and enabled/disabled
- * status of the UserDetails
because this is
- * authentication-related and should have been enforced by another provider server. The
- * UserDetails
returned by implementations is stored in the
- * generated AuthenticationToken
, so additional properties
- * such as email addresses, telephone numbers etc can easily be stored.
- *
- *
- *
- * Implementations should not perform any caching. They will only be called
- * when a refresh is required.
- *
- *
- * @author Ben Alex
- * @author Ray Krueger
- * @version $Id$
- */
-public interface UserDetailsService {
- /**
- * Obtains the granted authorities for the specified user.May throw any
- * AuthenticationException
or return null
if the authorities are unavailable.
- *
- * @param casUserId as obtained from the CAS validation service
- *
- * @return the details of the indicated user (at minimum the granted authorities and the username)
- *
- * @throws org.springframework.security.AuthenticationException DOCUMENT ME!
- */
- UserDetails getUserDetails(String casUserId)
- throws AuthenticationException;
-}
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 2903c5389b..d6471b045a 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
@@ -29,7 +29,11 @@ id =
ref =
## Defines a reference to a Spring bean Id.
attribute ref {xsd:string}
-
+
+cache-ref =
+ ## Defines a reference to a cache for use with a UserDetailsService.
+ attribute cache-ref {xsd:string}
+
user-service-ref =
## A reference to a user-service (or UserDetailsService bean) Id
attribute user-service-ref {xsd:string}
@@ -104,6 +108,8 @@ ldap-us.attlist &=
group-search-base-attribute?
ldap-us.attlist &=
group-role-attribute-attribute?
+ldap-us.attlist &=
+ cache-ref?
ldap-authentication-provider =
## Sets up an ldap authentication provider
@@ -391,7 +397,9 @@ jdbc-user-service =
jdbc-user-service.attlist &=
## The bean ID of the DataSource which provides the required tables.
attribute data-source-ref {xsd:string}
-
+jdbc-user-service.attlist &=
+ cache-ref?
+
any-user-service = user-service | jdbc-user-service | ldap-user-service
custom-filter =
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 4cf2c23cf7..8a67d2919f 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
@@ -1,2058 +1,1199 @@
-
-
-
-
-
-
-
- Defines the hashing algorithm used on user passwords. We recommend
- strongly against using MD4, as it is a very weak hashing algorithm.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Whether a string should be base64 encoded
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Defines the type of pattern used to specify URL paths (either JDK
- 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to "ant" if
- unspecified.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specifies an IP port number. Used to configure an embedded LDAP server,
- for example.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specifies a URL.
-
-
-
-
-
-
-
-
-
-
-
-
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Defines a reference to a Spring bean Id.
-
-
-
-
-
-
-
-
-
-
-
-
-
- A reference to a user-service (or UserDetailsService bean) Id
-
-
-
-
-
-
-
-
-
-
- element which defines a password encoding strategy. Used by an
- authentication provider to convert submitted passwords to hashed versions, for example.
-
-
-
-
-
-
-
-
-
-
-
-
-
- A property of the UserDetails object which will be used as salt by
- a password encoder. Typically something like "username" might be used.
-
-
-
-
-
-
-
-
-
- A single value that will be used as the salt for a password
- encoder.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Defines a reference to a Spring bean Id.
-
-
-
-
-
-
-
-
-
- Defines the hashing algorithm used on user passwords. We recommend
- strongly against using MD4, as it is a very weak hashing algorithm.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Whether a string should be base64 encoded
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A property of the UserDetails object which will be used as salt by a
- password encoder. Typically something like "username" might be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
- A single value that will be used as the salt for a password encoder.
-
-
-
-
-
-
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
-
-
-
-
-
-
-
-
- Specifies a URL.
-
-
-
-
-
-
-
-
-
- Specifies an IP port number. Used to configure an embedded LDAP server,
- for example.
-
-
-
-
-
-
-
-
-
- Username (DN) of the "manager" user identity which will be used to
- authenticate to a (non-embedded) LDAP server. If omitted, anonymous access will be used.
-
-
-
-
-
-
-
-
-
-
-
- Explicitly specifies an ldif file resource to load into an embedded LDAP
- server
-
-
-
-
-
-
-
-
-
- Optional root suffix for the embedded LDAP server. Default is
- "dc=springframework,dc=org"
-
-
-
-
-
-
-
-
-
-
-
-
-
- The optional server to use. If omitted, and a default LDAP server is
- registered (using <ldap-server> with no Id), that server will be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Group search filter. Defaults to (uniqueMember={0}). The substituted
- parameter is the DN of the user.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Search base for group membership searches. Defaults to "ou=groups".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Search base for user searches. Defaults to "".
-
-
-
-
-
-
-
-
-
-
-
-
-
- The LDAP attribute name which contains the role name which will be used
- within Spring Security. Defaults to "cn".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
-
-
-
-
-
-
-
-
- The optional server to use. If omitted, and a default LDAP server is
- registered (using <ldap-server> with no Id), that server will be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Group search filter. Defaults to (uniqueMember={0}). The substituted
- parameter is the DN of the user.
-
-
-
-
-
-
-
-
-
- Search base for group membership searches. Defaults to "ou=groups".
-
-
-
-
-
-
-
-
-
- The LDAP attribute name which contains the role name which will be used
- within Spring Security. Defaults to "cn".
-
-
-
-
-
-
-
-
-
-
- Sets up an ldap authentication provider
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The optional server to use. If omitted, and a default LDAP server is
- registered (using <ldap-server> with no Id), that server will be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Search base for group membership searches. Defaults to "ou=groups".
-
-
-
-
-
-
-
-
-
- Group search filter. Defaults to (uniqueMember={0}). The substituted
- parameter is the DN of the user.
-
-
-
-
-
-
-
-
-
- The LDAP attribute name which contains the role name which will be used
- within Spring Security. Defaults to "cn".
-
-
-
-
-
-
-
-
-
- A specific pattern used to build the user's DN, for example
- "uid={0},ou=people". The key "{0}" must be present and will be substituted with the
- username.
-
-
-
-
-
-
-
-
-
-
- Specifies that an LDAP provider should use an LDAP compare operation of the
- user's password to authenticate the user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The attribute in the directory which contains the user password. Defaults
- to "userPassword".
-
-
-
-
-
-
-
-
-
- Defines the hashing algorithm used on user passwords. We recommend
- strongly against using MD4, as it is a very weak hashing algorithm.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Can be used inside a bean definition to add a security interceptor to the
- bean and set up access configuration attributes for the bean's methods
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Optional AccessDecisionManager bean ID to be used by the created method
- security interceptor.
-
-
-
-
-
-
-
-
-
-
- Defines a protected method and the access control configuration attributes
- that apply to it. We strongly advise you NOT to mix "protect" declarations with any services
- provided "global-method-security".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A method name
-
-
-
-
-
-
-
-
-
- Access configuration attributes list that applies to the method, e.g.
- "ROLE_A,ROLE_B".
-
-
-
-
-
-
-
-
-
-
- Provides method security for all beans registered in the Spring application
- context. Specifically, beans will be scanned for Spring Security annotations and/or matches
- with the ordered list of "protect-pointcut" sub-elements. Where there is a match, the beans
- will automatically be proxied and security authorization applied to the methods accordingly.
- If you use and enable all three sources of method security metadata (ie "protect-pointcut"
- declarations, @Secured and also JSR 250 security annotations), the metadata sources will be
- queried in that order. In practical terms, this enables you to use XML to override method
- security metadata expressed by way of @Secured annotations, with @Secured annotations
- overriding method security metadata expressed by JSR 250 annotations. It is perfectly
- acceptable to mix and match, with a given Java type using a combination of XML, @Secured and
- JSR 250 to express method security metadata (albeit on different methods).
-
-
-
-
-
-
-
-
-
- Defines a protected pointcut and the access control configuration
- attributes that apply to it. Every bean registered in the Spring application context
- that provides a method that matches the pointcut will receive security authorization.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specifies whether the use of Spring Security's @Secured annotations should
- be enabled for this application context. Please ensure you have the
- spring-security-tiger-xxx.jar on the classpath. Defaults to "disabled".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specifies whether JSR-250 style attributes are to be used (for example
- "RolesAllowed"). This will require the javax.annotation.security classes on the classpath.
- Defaults to "disabled".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Optional AccessDecisionManager bean ID to override the default used for
- method security.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- An AspectJ expression, including the 'execution' keyword. For example,
- 'execution(int com.foo.TargetObject.countLength(String))' (without the quotes).
-
-
-
-
-
-
-
-
-
- Access configuration attributes list that applies to all methods matching
- the pointcut, e.g. "ROLE_A,ROLE_B"
-
-
-
-
-
-
-
-
-
-
- Container element for HTTP security configuration
-
-
-
-
-
-
-
-
-
- Specifies the access attributes and/or filter list for a particular
- set of URLs.
-
-
-
-
-
-
-
-
-
-
-
-
- Sets up a form login configuration for authentication with a username
- and password
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adds support for X.509 client authentication.
-
-
-
-
-
-
-
-
-
-
-
-
- Adds support for basic authentication (this is an element to permit
- future expansion, such as supporting an "ignoreFailure" attribute)
-
-
-
-
-
-
-
-
- Incorporates a logout processing filter. Most web applications require
- a logout filter, although you may not require one if you write a controller to
- provider similar logic.
-
-
-
-
-
-
-
-
-
-
-
-
- Adds support for concurrent session control, allowing limits to be
- placed on the number of sessions a user can have.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adds support for automatically granting all anonymous web requests a
- particular principal identity and a corresponding granted authority.
-
-
-
-
-
-
-
-
-
-
-
-
- Defines the list of mappings between http and https ports for use in
- redirects
-
-
-
-
+ xmlns:security="http://www.springframework.org/schema/security" elementFormDefault="qualified"
+ targetNamespace="http://www.springframework.org/schema/security">
+
+
+
+ Defines the hashing algorithm used on user passwords. We recommend
+ strongly against using MD4, as it is a very weak hashing algorithm.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Whether a string should be base64 encoded
+
+
+
+
+
+
+
+
+
+
+
+
+ Defines the type of pattern used to specify URL paths (either JDK
+ 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to
+ "ant" if unspecified.
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies an IP port number. Used to configure an embedded LDAP
+ server, for example.
+
+
+
+
+
+
+ Specifies a URL.
+
+
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in the
+ context.
+
+
+
+
+
+
+ Defines a reference to a Spring bean Id.
+
+
+
+
+
+
+ Defines a reference to a cache for use with a UserDetailsService.
+
+
+
+
+
+
+ A reference to a user-service (or UserDetailsService bean) Id
+
+
+
+
+
+ element which defines a password encoding strategy. Used by an
+ authentication provider to convert submitted passwords to hashed versions, for
+ example.
+
+
-
-
-
+
+
+
+
+ A property of the UserDetails object which will be
+ used as salt by a password encoder. Typically something like
+ "username" might be used.
+
+
+
+
+ A single value that will be used as the salt for a
+ password encoder.
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Automatically registers a login form, BASIC authentication, anonymous
- authentication, logout services, remember-me and servlet-api-integration. If set to
- "true", all of these capabilities are added (although you can still customize the
- configuration of each by providing the respective element). If unspecified, defaults to
- "false".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Controls the eagerness with which an HTTP session is created. If not set,
- defaults to "ifRequired".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Defines the type of pattern used to specify URL paths (either JDK
- 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to "ant" if
- unspecified.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Whether test URLs should be converted to lower case prior to comparing
- with defined path patterns. If unspecified, defaults to "true".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Provides versions of HttpServletRequest security methods such as
- isUserInRole() and getPrincipal() which are implemented by accessing the Spring
- SecurityContext. Defaults to "true".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Optional attribute specifying the ID of the AccessDecisionManager
- implementation which should be used for authorizing HTTP requests.
-
-
-
-
-
-
-
-
-
- Optional attribute specifying the realm name that will be used for all
- authentication features that require a realm name (eg BASIC and Digest authentication). If
- unspecified, defaults to "Spring Security Application".
-
-
-
-
-
-
-
-
-
- Indicates whether an existing session should be invalidated when a user
- authenticates and a new session started. If set to "none" no change will be made.
- "newSession" will create a new empty session. "migrateSession" will create a new session
- and copy the session attributes to the new session. Defaults to "migrateSession".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pattern which defines the URL path. The content will depend on the
- type set in the containing http element, so will default to ant path syntax.
-
-
-
-
-
-
-
-
-
- The access configuration attributes that apply for the configured path.
-
-
-
-
-
-
-
-
-
- The HTTP Method for which the access configuration attributes should
- apply. If not specified, the attributes will apply to any method.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The filter list for the path. Currently can be set to "none" to remove a
- path from having any filters applied. The full filter stack (consisting of all defined
- filters, will be applied to any other paths).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to specify that a URL must be accessed over http or https
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specifies the URL that will cause a logout. Spring Security will
- initialize a filter that responds to this particular URL. Defaults to
- /j_spring_security_logout if unspecified.
-
-
-
-
-
-
-
-
-
- Specifies the URL to display once the user has logged out. If not
- specified, defaults to /.
-
-
-
-
-
-
-
-
-
- Specifies whether a logout also causes HttpSession invalidation, which is
- generally desirable. If unspecified, defaults to true.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The URL that the login form is posted to. If unspecified, it defaults to
- /j_spring_security_check.
-
-
-
-
-
-
-
-
-
- The URL that will be redirected to after successful authentication, if the
- user's previous action could not be resumed. This generally happens if the user visits a
- login page without having first requested a secured operation that triggers
- authentication. If unspecified, defaults to the root of the application.
-
-
-
-
-
-
-
-
-
- The URL for the login page. If no login URL is specified, Spring Security
- will automatically create a login URL at /spring_security_login and a corresponding filter
- to render that login URL when requested.
-
-
-
-
-
-
-
-
-
- The URL for the login failure page. If no login failure URL is specified,
- Spring Security will automatically create a failure login URL at
- /spring_security_login?login_error and a corresponding filter to render that login failure
- URL when requested.
-
-
-
-
-
-
-
-
-
-
- Sets up form login for authentication with an Open ID identity
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Defines a reference to a Spring bean Id.
+
+
+
+
+ Defines the hashing algorithm used on user passwords. We recommend
+ strongly against using MD4, as it is a very weak hashing algorithm.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Whether a string should be base64 encoded
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A property of the UserDetails object which will be used as salt by
+ a password encoder. Typically something like "username" might be used.
+
+
+
+
+
+
+ A single value that will be used as the salt for a password
+ encoder.
+
+
+
+
-
- A reference to a user-service (or UserDetailsService bean) Id
-
+ 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.
-
-
-
-
-
-
-
-
-
- Used to explicitly configure a FilterChainProxy instance with a
- FilterChainMap
-
-
-
-
-
-
-
-
-
- Used within filter-chain-map to define a specific URL pattern and the
- list of filters which apply to the URLs matching that pattern. When multiple
- filter-chain elements are used within a filter-chain-map element, the most specific
- patterns must be placed at the top of the list, with most general ones at the bottom.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to explicitly configure a FilterInvocationDefinitionSource bean for use
- with a FilterSecurityInterceptor. Usually only needed if you are configuring a
- FilterChainProxy explicitly, rather than using the <http> element. The
- intercept-url elements used should only contain pattern, method and access attributes. Any
- others will result in a configuration error.
-
-
-
-
-
-
-
-
-
- Specifies the access attributes and/or filter list for a particular
- set of URLs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
-
-
-
-
-
-
-
-
- as for http element
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Defines the type of pattern used to specify URL paths (either JDK
- 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to "ant" if
- unspecified.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The key shared between the provider and filter. This generally does not
- need to be set. If unset, it will default to "doesNotMatter".
-
-
-
-
-
-
-
-
-
- The username that should be assigned to the anonymous request. This allows
- the principal to be identified, which may be important for logging and auditing. if unset,
- defaults to "anonymousUser".
-
-
-
-
-
-
-
-
-
- The granted authority that should be assigned to the anonymous request.
- Commonly this is used to assign the anonymous request particular roles, which can
- subsequently be used in authorization decisions. If unset, defaults to "ROLE_ANONYMOUS".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The regular expression used to obtain the username from the certificate's
- subject. Defaults to matching on the common name using the pattern "CN=(.*?),".
-
-
-
-
-
-
-
-
-
- A reference to a user-service (or UserDetailsService bean) Id
-
-
-
-
-
-
-
-
-
-
- If you are using namespace configuration with Spring Security, an
- AuthenticationManager will automatically be registered. This element simple allows you to
- define an alias to allow you to reference the authentication-manager in your own beans.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The alias you wish to use for the AuthenticationManager bean
-
-
-
-
-
-
-
-
-
-
- Indicates that the contained user-service should be used as an
- authentication source.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A reference to a user-service (or UserDetailsService bean) Id
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Creates an in-memory UserDetailsService from a properties file or a list of
- "user" child elements.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in the
+ context.
+
+
+
+
+ Specifies a URL.
+
+
+
+
+ Specifies an IP port number. Used to configure an embedded LDAP
+ server, for example.
+
+
+
+
+ Username (DN) of the "manager" user identity which will be used to
+ authenticate to a (non-embedded) LDAP server. If omitted, anonymous access will
+ be used.
+
+
+
+
+
+ Explicitly specifies an ldif file resource to load into an
+ embedded LDAP server
+
+
+
+
+ Optional root suffix for the embedded LDAP server. Default is
+ "dc=springframework,dc=org"
+
+
+
+
+
+
+ The optional server to use. If omitted, and a default LDAP server
+ is registered (using <ldap-server> with no Id), that server will
+ be used.
+
+
+
+
+
+
+ Group search filter. Defaults to (uniqueMember={0}). The
+ substituted parameter is the DN of the user.
+
+
+
+
+
+
+ Search base for group membership searches. Defaults to
+ "ou=groups".
+
+
+
+
+
+
+
+
+
+ Search base for user searches. Defaults to "".
+
+
+
+
+
+
+ The LDAP attribute name which contains the role name which will be
+ used within Spring Security. Defaults to "cn".
+
+
+
+
+
+
+
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in the
+ context.
+
+
+
+
+ The optional server to use. If omitted, and a default LDAP server
+ is registered (using <ldap-server> with no Id), that server will
+ be used.
+
+
+
+
+
+
+ Group search filter. Defaults to (uniqueMember={0}). The
+ substituted parameter is the DN of the user.
+
+
+
+
+ Search base for group membership searches. Defaults to
+ "ou=groups".
+
+
+
+
+ The LDAP attribute name which contains the role name which will be
+ used within Spring Security. Defaults to "cn".
+
+
+
+
+ Defines a reference to a cache for use with a UserDetailsService.
+
+
+
+
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
+ Sets up an ldap authentication provider
+
+
+
+
+
+
+
+
+
+
+ The optional server to use. If omitted, and a default LDAP server
+ is registered (using <ldap-server> with no Id), that server will
+ be used.
+
+
+
+
+
+
+ Search base for group membership searches. Defaults to
+ "ou=groups".
+
+
+
+
+ Group search filter. Defaults to (uniqueMember={0}). The
+ substituted parameter is the DN of the user.
+
+
+
+
+ The LDAP attribute name which contains the role name which will be
+ used within Spring Security. Defaults to "cn".
+
+
+
+
+ A specific pattern used to build the user's DN, for example
+ "uid={0},ou=people". The key "{0}" must be present and will be substituted with
+ the username.
+
+
+
+
+
+ Specifies that an LDAP provider should use an LDAP compare operation
+ of the user's password to authenticate the user
+
+
+
+
+
+
+
+
+
+
+
+ The attribute in the directory which contains the user password.
+ Defaults to "userPassword".
+
+
+
+
+ Defines the hashing algorithm used on user passwords. We recommend
+ strongly against using MD4, as it is a very weak hashing algorithm.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Can be used inside a bean definition to add a security interceptor to
+ the bean and set up access configuration attributes for the bean's methods
+
+
+
+
+
+
+
+
+
+
+
+ Optional AccessDecisionManager bean ID to be used by the created
+ method security interceptor.
+
+
+
+
+
+ Defines a protected method and the access control configuration
+ attributes that apply to it. We strongly advise you NOT to mix "protect"
+ declarations with any services provided "global-method-security".
+
+
+
+
+
+
+
+
+ A method name
+
+
+
+
+ Access configuration attributes list that applies to the method,
+ e.g. "ROLE_A,ROLE_B".
+
+
+
+
+
+ Provides method security for all beans registered in the Spring
+ application context. Specifically, beans will be scanned for Spring Security
+ annotations and/or matches with the ordered list of "protect-pointcut" sub-elements.
+ Where there is a match, the beans will automatically be proxied and security
+ authorization applied to the methods accordingly. If you use and enable all three
+ sources of method security metadata (ie "protect-pointcut" declarations, @Secured
+ and also JSR 250 security annotations), the metadata sources will be queried in that
+ order. In practical terms, this enables you to use XML to override method security
+ metadata expressed by way of @Secured annotations, with @Secured annotations
+ overriding method security metadata expressed by JSR 250 annotations. It is
+ perfectly acceptable to mix and match, with a given Java type using a combination of
+ XML, @Secured and JSR 250 to express method security metadata (albeit on different
+ methods).
+
+
+
+
+
+ Defines a protected pointcut and the access control
+ configuration attributes that apply to it. Every bean registered in the
+ Spring application context that provides a method that matches the
+ pointcut will receive security authorization.
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies whether the use of Spring Security's @Secured
+ annotations should be enabled for this application context. Please ensure you
+ have the spring-security-tiger-xxx.jar on the classpath. Defaults to "disabled".
+
+
+
+
+
+
+
+
+
+
+ Specifies whether JSR-250 style attributes are to be used (for
+ example "RolesAllowed"). This will require the javax.annotation.security classes
+ on the classpath. Defaults to "disabled".
+
+
+
+
+
+
+
+
+
+
+ Optional AccessDecisionManager bean ID to override the default
+ used for method security.
+
+
+
-
+
+
+
+ An AspectJ expression, including the 'execution' keyword. For
+ example, 'execution(int com.foo.TargetObject.countLength(String))' (without the
+ quotes).
+
+
+
+
+ Access configuration attributes list that applies to all methods
+ matching the pointcut, e.g. "ROLE_A,ROLE_B"
+
+
+
+
+
+ Container element for HTTP security configuration
+
+
+
+
+
+ Specifies the access attributes and/or filter list for a
+ particular set of URLs.
+
+
+
+
+
+
+
+ Sets up a form login configuration for authentication with
+ a username and password
+
+
+
+
+
+
+
+
+ Adds support for X.509 client authentication.
+
+
+
+
+
+
+
+ Adds support for basic authentication (this is an element
+ to permit future expansion, such as supporting an "ignoreFailure"
+ attribute)
+
+
+
+
+
+ Incorporates a logout processing filter. Most web
+ applications require a logout filter, although you may not require one
+ if you write a controller to provider similar logic.
+
+
+
+
+
+
+
+ Adds support for concurrent session control, allowing
+ limits to be placed on the number of sessions a user can have.
+
+
+
+
+
+
+
+
+
+
+
+
+ Adds support for automatically granting all anonymous web
+ requests a particular principal identity and a corresponding granted
+ authority.
+
+
+
+
+
+
+
+ Defines the list of mappings between http and https ports
+ for use in redirects
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Automatically registers a login form, BASIC authentication,
+ anonymous authentication, logout services, remember-me and
+ servlet-api-integration. If set to "true", all of these capabilities are added
+ (although you can still customize the configuration of each by providing the
+ respective element). If unspecified, defaults to "false".
+
+
+
+
+
+
+
+
+
+
+ Controls the eagerness with which an HTTP session is created. If
+ not set, defaults to "ifRequired".
+
+
+
+
+
+
+
+
+
+
+
+ Defines the type of pattern used to specify URL paths (either JDK
+ 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to
+ "ant" if unspecified.
+
+
+
+
+
+
+
+
+
+
+ Whether test URLs should be converted to lower case prior to
+ comparing with defined path patterns. If unspecified, defaults to "true".
+
+
+
+
+
+
+
+
+
+
+ Provides versions of HttpServletRequest security methods such as
+ isUserInRole() and getPrincipal() which are implemented by accessing the Spring
+ SecurityContext. Defaults to "true".
+
+
+
+
+
+
+
+
+
+
+ Optional attribute specifying the ID of the AccessDecisionManager
+ implementation which should be used for authorizing HTTP requests.
+
+
+
+
+ Optional attribute specifying the realm name that will be used for
+ all authentication features that require a realm name (eg BASIC and Digest
+ authentication). If unspecified, defaults to "Spring Security Application".
+
+
+
+
+ Indicates whether an existing session should be invalidated when a
+ user authenticates and a new session started. If set to "none" no change will be
+ made. "newSession" will create a new empty session. "migrateSession" will create
+ a new session and copy the session attributes to the new session. Defaults to
+ "migrateSession".
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+ The pattern which defines the URL path. The content will depend on
+ the type set in the containing http element, so will default to ant path syntax.
+
+
+
+
+ The access configuration attributes that apply for the configured
+ path.
+
+
+
+
+ The HTTP Method for which the access configuration attributes
+ should apply. If not specified, the attributes will apply to any method.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The filter list for the path. Currently can be set to "none" to
+ remove a path from having any filters applied. The full filter stack (consisting
+ of all defined filters, will be applied to any other paths).
+
+
+
+
+
+
+
+
+
+ Used to specify that a URL must be accessed over http or https
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+ Specifies the URL that will cause a logout. Spring Security will
+ initialize a filter that responds to this particular URL. Defaults to
+ /j_spring_security_logout if unspecified.
+
+
+
+
+ Specifies the URL to display once the user has logged out. If not
+ specified, defaults to /.
+
+
+
+
+ Specifies whether a logout also causes HttpSession invalidation,
+ which is generally desirable. If unspecified, defaults to true.
+
+
+
+
+
+
+
+
+
-
+
+
+
+ The URL that the login form is posted to. If unspecified, it
+ defaults to /j_spring_security_check.
+
+
+
+
+ The URL that will be redirected to after successful
+ authentication, if the user's previous action could not be resumed. This
+ generally happens if the user visits a login page without having first requested
+ a secured operation that triggers authentication. If unspecified, defaults to
+ the root of the application.
+
+
+
+
+ The URL for the login page. If no login URL is specified, Spring
+ Security will automatically create a login URL at /spring_security_login and a
+ corresponding filter to render that login URL when requested.
+
+
+
+
+ The URL for the login failure page. If no login failure URL is
+ specified, Spring Security will automatically create a failure login URL at
+ /spring_security_login?login_error and a corresponding filter to render that
+ login failure URL when requested.
+
+
+
+
+
+ Sets up form login for authentication with an Open ID identity
+
+
+
+
+
+ A reference to a user-service (or UserDetailsService bean) Id
+
+
+
+
+
+
+ Used to explicitly configure a FilterChainProxy instance with a
+ FilterChainMap
+
+
+
+
+
+ Used within filter-chain-map to define a specific URL
+ pattern and the list of filters which apply to the URLs matching that
+ pattern. When multiple filter-chain elements are used within a
+ filter-chain-map element, the most specific patterns must be placed at
+ the top of the list, with most general ones at the bottom.
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+ Used to explicitly configure a FilterInvocationDefinitionSource bean
+ for use with a FilterSecurityInterceptor. Usually only needed if you are configuring
+ a FilterChainProxy explicitly, rather than using the <http> element.
+ The intercept-url elements used should only contain pattern, method and access
+ attributes. Any others will result in a configuration error.
+
+
+
+
+
+ Specifies the access attributes and/or filter list for a
+ particular set of URLs.
+
+
+
+
+
+
+
+
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in the
+ context.
+
+
+
+
+ as for http element
+
+
+
+
+
+
+
+
+
+
+ Defines the type of pattern used to specify URL paths (either JDK
+ 1.4-compatible regular expressions, or Apache Ant expressions). Defaults to
+ "ant" if unspecified.
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
- Represents a user in the application.
+
+
+
+ The key shared between the provider and filter. This generally
+ does not need to be set. If unset, it will default to "doesNotMatter".
+
+
+
+
+ The username that should be assigned to the anonymous request.
+ This allows the principal to be identified, which may be important for logging
+ and auditing. if unset, defaults to "anonymousUser".
+
+
+
+
+ The granted authority that should be assigned to the anonymous
+ request. Commonly this is used to assign the anonymous request particular roles,
+ which can subsequently be used in authorization decisions. If unset, defaults to
+ "ROLE_ANONYMOUS".
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The username assigned to the user.
-
-
-
-
-
-
-
-
-
- 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).
-
-
-
-
-
-
-
-
-
- One of more authorities granted to the user. Separate authorities with a
- comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR"
-
-
-
-
-
-
-
-
-
- Can be set to "true" to mark an account as locked and unusable.
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The regular expression used to obtain the username from the
+ certificate's subject. Defaults to matching on the common name using the pattern
+ "CN=(.*?),".
+
+
+
+
+ A reference to a user-service (or UserDetailsService bean) Id
+
+
+
+
+
+ If you are using namespace configuration with Spring Security, an
+ AuthenticationManager will automatically be registered. This element simple allows
+ you to define an alias to allow you to reference the authentication-manager in your
+ own beans.
+
+
+
+
+
+
+
+ The alias you wish to use for the AuthenticationManager bean
+
+
+
+
+
+ Indicates that the contained user-service should be used as an
+ authentication source.
+
+
+
+
+
+
+
+
+
+
+
+
+ A reference to a user-service (or UserDetailsService bean) Id
+
+
+
+
+
+
+
+
+ Creates an in-memory UserDetailsService from a properties file or a
+ list of "user" child elements.
+
+
+
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in
+ the context.
+
+
+
+
+
+
+
+
+
+
+ Represents a user in the application.
+
+
+
+
+
+
+
+
+ The username assigned to the user.
+
+
+
+
+ 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).
+
+
+
+
+ One of more authorities granted to the user. Separate authorities
+ with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR"
+
+
+
+
+ Can be set to "true" to mark an account as locked and unusable.
+
+
+
+
+
+
+
+
+
+
+
+ Causes creation of a JDBC-based UserDetailsService.
+
+
+
+
+ A bean identifier, used for referring to the bean elsewhere in
+ the context.
+
+
+
+
+
+
+
+
+ The bean ID of the DataSource which provides the required tables.
+
+
+
+
+ Defines a reference to a cache for use with a UserDetailsService.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Used to indicate that a filter bean declaration should be incorporated
+ into the security filter chain. If neither the 'after' or 'before' options are
+ supplied, then the filter must implement the Ordered interface directly.
+
+
+
+
+ The filter immediately after which the custom-filter should be
+ placed in the chain. This feature will only be needed by advanced users who
+ wish to mix their own filters into the security filter chain and have some
+ knowledge of the standard Spring Security filters. The filter names map to
+ specific Spring Security implementation filters.
+
+
+
+
+ The filter immediately before which the custom-filter should
+ be placed in the chain
+
+
+
+
+
+
+
+ The filter immediately after which the custom-filter should be
+ placed in the chain. This feature will only be needed by advanced users who wish
+ to mix their own filters into the security filter chain and have some knowledge
+ of the standard Spring Security filters. The filter names map to specific Spring
+ Security implementation filters.
+
+
+
+
+
+
+ The filter immediately before which the custom-filter should be
+ placed in the chain
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
- Causes creation of a JDBC-based UserDetailsService.
-
-
-
-
-
-
-
-
- A bean identifier, used for referring to the bean elsewhere in the
- context.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The bean ID of the DataSource which provides the required tables.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to indicate that a filter bean declaration should be incorporated into
- the security filter chain. If neither the 'after' or 'before' options are supplied, then the
- filter must implement the Ordered interface directly.
-
-
-
-
-
-
-
-
- The filter immediately after which the custom-filter should be placed in
- the chain. This feature will only be needed by advanced users who wish to mix their own
- filters into the security filter chain and have some knowledge of the standard Spring
- Security filters. The filter names map to specific Spring Security implementation
- filters.
-
-
-
-
-
-
-
-
-
- The filter immediately before which the custom-filter should be placed
- in the chain
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The filter immediately after which the custom-filter should be placed in
- the chain. This feature will only be needed by advanced users who wish to mix their own
- filters into the security filter chain and have some knowledge of the standard Spring
- Security filters. The filter names map to specific Spring Security implementation filters.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The filter immediately before which the custom-filter should be placed in
- the chain
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
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 35dbc40224..74832ef7ac 100644
--- a/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java
+++ b/core/src/test/java/org/springframework/security/config/JdbcUserServiceBeanDefinitionParserTests.java
@@ -1,16 +1,17 @@
package org.springframework.security.config;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import org.junit.Test;
import org.junit.After;
-
+import org.junit.Test;
+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.jdbc.JdbcUserDetailsManager;
import org.springframework.security.util.InMemoryXmlApplicationContext;
-import org.springframework.security.AuthenticationManager;
-import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
-
-import javax.sql.DataSource;
/**
* @author Ben Alex
@@ -18,7 +19,7 @@ import javax.sql.DataSource;
* @version $Id$
*/
public class JdbcUserServiceBeanDefinitionParserTests {
- private InMemoryXmlApplicationContext appContext;
+ private static String USER_CACHE_XML = "";
private static String DATA_SOURCE =
" " +
@@ -29,6 +30,8 @@ public class JdbcUserServiceBeanDefinitionParserTests {
" " +
" ";
+ private InMemoryXmlApplicationContext appContext;
+
@After
public void closeAppContext() {
if (appContext != null) {
@@ -45,10 +48,20 @@ public class JdbcUserServiceBeanDefinitionParserTests {
@Test
public void beanIdIsParsedCorrectly() {
- setContext("" + DATA_SOURCE);
- JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext.getBean("customUserService");
+ setContext("" + DATA_SOURCE);
+ JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext.getBean("myUserService");
}
+ @Test
+ public void cacheRefIsparsedCorrectly() {
+ setContext(""
+ + DATA_SOURCE +USER_CACHE_XML);
+ JdbcUserDetailsManager mgr = (JdbcUserDetailsManager) appContext.getBean("myUserService");
+ CachingUserDetailsService cachingUserService =
+ (CachingUserDetailsService) appContext.getBean("myUserService" + AbstractUserDetailsServiceBeanDefinitionParser.CACHING_SUFFIX);
+ assertSame(cachingUserService.getUserCache(), appContext.getBean("userCache"));
+ }
+
@Test
public void isSupportedByAuthenticationProviderElement() {
setContext(
@@ -59,6 +72,19 @@ public class JdbcUserServiceBeanDefinitionParserTests {
mgr.authenticate(new UsernamePasswordAuthenticationToken("rod", "koala"));
}
+ @Test
+ public void cacheIsInjectedIntoAuthenticationProvider() {
+ setContext(
+ "" +
+ " " +
+ "" + DATA_SOURCE + USER_CACHE_XML);
+ ProviderManager mgr = (ProviderManager) appContext.getBean(BeanIds.AUTHENTICATION_MANAGER);
+ DaoAuthenticationProvider provider = (DaoAuthenticationProvider) mgr.getProviders().get(0);
+ assertSame(provider.getUserCache(), appContext.getBean("userCache"));
+ provider.authenticate(new UsernamePasswordAuthenticationToken("rod","koala"));
+ assertNotNull("Cache should contain user after authentication", provider.getUserCache().getUserFromCache("rod"));
+ }
+
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}