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 *
    *
  1. If only one, use that one.
  2. *
  3. If more than one, use the form login entry point (if form login is being used), then try basic
  4. - *
  5. If still null, throw an exception (for now). TODO: Examine additional beans and types and make decision
  6. + *
  7. If still null, throw an exception (for now).
  8. *
* */ @@ -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); }