From 5953af0f6bdd1f53c94f0fc1fc0c45e940aa4455 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Mon, 3 Aug 2009 00:21:11 +0000 Subject: [PATCH] SEC-1196: Change use of to actually register the global ProviderManager instance. This element now registers the global ProviderManager instance and must contain any authentication-provider elements (or ldap-authentication-provider elements). --- .../security/config/Elements.java | 1 + ...serDetailsServiceBeanDefinitionParser.java | 2 +- ...enticationManagerBeanDefinitionParser.java | 100 +++++++++++++++--- ...nticationProviderBeanDefinitionParser.java | 99 ++++++++--------- ...cationProviderBeanDefinitionDecorator.java | 8 +- .../HttpSecurityBeanDefinitionParser.java | 8 +- .../LdapProviderBeanDefinitionParser.java | 7 +- ...balMethodSecurityBeanDefinitionParser.java | 2 - ...terceptMethodsBeanDefinitionDecorator.java | 2 - .../security/config/spring-security-3.0.rnc | 14 ++- .../security/config/spring-security-3.0.xsd | 26 ++--- .../security/config/ConfigTestUtils.java | 4 +- ...ationManagerBeanDefinitionParserTests.java | 27 ++--- ...tionProviderBeanDefinitionParserTests.java | 14 ++- ...nProviderBeanDefinitionDecoratorTests.java | 33 +----- ...cUserServiceBeanDefinitionParserTests.java | 12 ++- ...HttpSecurityBeanDefinitionParserTests.java | 6 +- ...LdapProviderBeanDefinitionParserTests.java | 25 +++-- ...thodSecurityBeanDefinitionParserTests.java | 8 +- ...ptMethodsBeanDefinitionDecoratorTests.java | 19 +--- ...SecurityInterceptorWithAopConfigTests.java | 4 +- .../security/config/method-security.xml | 18 ++-- .../security/config/users.properties | 0 .../WEB-INF/applicationContext-security.xml | 10 +- .../applicationContext-contacts-test.xml | 10 +- samples/openid/pom.xml | 28 +++-- .../WEB-INF/applicationContext-security.xml | 22 +--- .../WEB-INF/applicationContext-security.xml | 11 +- .../WEB-INF/applicationContext-security.xml | 22 ++-- 29 files changed, 298 insertions(+), 244 deletions(-) rename {core => config}/src/test/resources/org/springframework/security/config/method-security.xml (66%) rename {core => config}/src/test/resources/org/springframework/security/config/users.properties (100%) diff --git a/config/src/main/java/org/springframework/security/config/Elements.java b/config/src/main/java/org/springframework/security/config/Elements.java index 1c60cef57b..7d62d347dd 100644 --- a/config/src/main/java/org/springframework/security/config/Elements.java +++ b/config/src/main/java/org/springframework/security/config/Elements.java @@ -41,6 +41,7 @@ public abstract class Elements { public static final String PORT_MAPPINGS = "port-mappings"; public static final String PORT_MAPPING = "port-mapping"; public static final String CUSTOM_FILTER = "custom-filter"; + @Deprecated public static final String CUSTOM_AUTH_PROVIDER = "custom-authentication-provider"; public static final String CUSTOM_AFTER_INVOCATION_PROVIDER = "custom-after-invocation-provider"; public static final String X509 = "x509"; diff --git a/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java index e46c257e74..8696e2c8f7 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java @@ -20,7 +20,7 @@ import org.w3c.dom.Element; * @version $Id$ */ public abstract class AbstractUserDetailsServiceBeanDefinitionParser implements BeanDefinitionParser { - private static final String CACHE_REF = "cache-ref"; + 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) */ diff --git a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java index 296b9a7253..a3be870c86 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java @@ -1,44 +1,112 @@ package org.springframework.security.config.authentication; +import java.util.List; + +import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.parsing.CompositeComponentDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.NamespaceHandlerResolver; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.BeanIds; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** - * Registers an alias name for the default ProviderManager used by the namespace - * configuration, allowing users to reference it in their beans and clearly see where the name is - * coming from. Also allows the ConcurrentSessionController to be set on the ProviderManager. + * Registers the central ProviderManager used by the namespace configuration, and allows the configuration of an + * alias, allowing users to reference it in their beans and clearly see where the name is + * coming from. * * @author Luke Taylor * @version $Id$ */ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinitionParser { - private static final String ATT_SESSION_CONTROLLER_REF = "session-controller-ref"; private static final String ATT_ALIAS = "alias"; + private static final String ATT_REF = "ref"; - public BeanDefinition parse(Element element, ParserContext parserContext) { - ConfigUtils.registerProviderManagerIfNecessary(parserContext, element); + public BeanDefinition parse(Element element, ParserContext pc) { + Assert.state(!pc.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER), + "AuthenticationManager has already been registered!"); + pc.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element))); + + BeanDefinitionBuilder providerManagerBldr = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class); String alias = element.getAttribute(ATT_ALIAS); - if (!StringUtils.hasText(alias)) { - parserContext.getReaderContext().error(ATT_ALIAS + " is required.", element ); + checkForDeprecatedSessionControllerRef(element, pc); + List providers = new ManagedList(); + NamespaceHandlerResolver resolver = pc.getReaderContext().getNamespaceHandlerResolver(); + + NodeList children = element.getChildNodes(); + + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + if (node instanceof Element) { + Element providerElt = (Element)node; + if (StringUtils.hasText(providerElt.getAttribute(ATT_REF))) { + providers.add(new RuntimeBeanReference(providerElt.getAttribute(ATT_REF))); + } else { + BeanDefinition provider = resolver.resolve(providerElt.getNamespaceURI()).parse(providerElt, pc); + Assert.notNull(provider, "Parser for " + providerElt.getNodeName() + " returned a null bean definition"); + providers.add(provider); + } + } } - String sessionControllerRef = element.getAttribute(ATT_SESSION_CONTROLLER_REF); - - if (StringUtils.hasText(sessionControllerRef)) { - parserContext.getReaderContext().warning(ATT_SESSION_CONTROLLER_REF + " is not supported in Spring Security " + - " 3.0 and will be ignored. Use the attribute on the element instead.", - parserContext.extractSource(element)); + if (providers.isEmpty()) { + providers.add(new RootBeanDefinition(NullAuthenticationProvider.class)); } - parserContext.getRegistry().registerAlias(BeanIds.AUTHENTICATION_MANAGER, alias); - parserContext.getReaderContext().fireAliasRegistered(BeanIds.AUTHENTICATION_MANAGER, alias, parserContext.extractSource(element)); + providerManagerBldr.addPropertyValue("providers", providers); + + BeanDefinition authManager = providerManagerBldr.getBeanDefinition(); + pc.getRegistry().registerBeanDefinition(BeanIds.AUTHENTICATION_MANAGER, authManager); + pc.registerBeanComponent(new BeanComponentDefinition(authManager, BeanIds.AUTHENTICATION_MANAGER)); + + if (StringUtils.hasText(alias)) { + pc.getRegistry().registerAlias(BeanIds.AUTHENTICATION_MANAGER, alias); + pc.getReaderContext().fireAliasRegistered(BeanIds.AUTHENTICATION_MANAGER, alias, pc.extractSource(element)); + } + + pc.popAndRegisterContainingComponent(); return null; } + + private void checkForDeprecatedSessionControllerRef(Element element, ParserContext pc) { + final String ATT_SESSION_CONTROLLER_REF = "session-controller-ref"; + + if (StringUtils.hasText(element.getAttribute(ATT_SESSION_CONTROLLER_REF))) { + pc.getReaderContext().warning(ATT_SESSION_CONTROLLER_REF + " is not supported in Spring Security " + + " 3.0 and will be ignored. Use the attribute on the element instead.", + pc.extractSource(element)); + } + } + + /** + * Provider which doesn't provide any service. Only used to prevent a configuration exception if the provider list + * is empty (usually because a child ProviderManager from the <http> namespace, such as OpenID, is expected + * to handle the request). + */ + public static final class NullAuthenticationProvider implements AuthenticationProvider { + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + return null; + } + + public boolean supports(Class authentication) { + return false; + } + } } diff --git a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java index c07d3a2bf4..0ac93d549d 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java @@ -1,17 +1,10 @@ package org.springframework.security.config.authentication; -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.parsing.BeanComponentDefinition; -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.core.Ordered; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.Elements; import org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser; @@ -48,11 +41,6 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio Element jdbcUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE); Element ldapUserServiceElt = DomUtils.getChildElementByTagName(element, Elements.LDAP_USER_SERVICE); - // 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); - parserContext.registerComponent(new BeanComponentDefinition(authProvider, id)); - String ref = element.getAttribute(ATT_USER_DETAILS_REF); if (StringUtils.hasText(ref)) { @@ -81,54 +69,67 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio parser.parse(elt, parserContext); ref = parser.getId(); + + // Pinch the cache-ref from the UserDetailService element, if set. + String cacheRef = elt.getAttribute(AbstractUserDetailsServiceBeanDefinitionParser.CACHE_REF); + + if (StringUtils.hasText(cacheRef)) { + authProvider.getPropertyValues().addPropertyValue("userCache", new RuntimeBeanReference(cacheRef)); + } } authProvider.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(ref)); - BeanDefinitionBuilder cacheResolverBldr = BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProviderCacheResolver.class); - cacheResolverBldr.addConstructorArgValue(id); - cacheResolverBldr.addConstructorArgValue(ref); - cacheResolverBldr.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - BeanDefinition cacheResolver = cacheResolverBldr.getBeanDefinition(); + // 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); +// parserContext.registerComponent(new BeanComponentDefinition(authProvider, id)); - String name = parserContext.getReaderContext().generateBeanName(cacheResolver); - parserContext.getRegistry().registerBeanDefinition(name , cacheResolver); - parserContext.registerComponent(new BeanComponentDefinition(cacheResolver, name)); - ConfigUtils.addAuthenticationProvider(parserContext, id, element); +// BeanDefinitionBuilder cacheResolverBldr = BeanDefinitionBuilder.rootBeanDefinition(AuthenticationProviderCacheResolver.class); +// cacheResolverBldr.addConstructorArgValue(id); +// cacheResolverBldr.addConstructorArgValue(ref); +// cacheResolverBldr.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); +// BeanDefinition cacheResolver = cacheResolverBldr.getBeanDefinition(); +// +// String name = parserContext.getReaderContext().generateBeanName(cacheResolver); +// parserContext.getRegistry().registerBeanDefinition(name , cacheResolver); +// parserContext.registerComponent(new BeanComponentDefinition(cacheResolver, name)); - return null; +// ConfigUtils.addAuthenticationProvider(parserContext, id, element); + + return authProvider; } /** * 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; - } - } +// 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/config/src/main/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecorator.java b/config/src/main/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecorator.java index 99ba390f44..9a94b6ac4a 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecorator.java +++ b/config/src/main/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecorator.java @@ -3,7 +3,7 @@ package org.springframework.security.config.authentication; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.xml.BeanDefinitionDecorator; import org.springframework.beans.factory.xml.ParserContext; -import org.w3c.dom.Element; +import org.springframework.security.config.Elements; import org.w3c.dom.Node; /** @@ -14,8 +14,12 @@ import org.w3c.dom.Node; * @version $Id$ */ public class CustomAuthenticationProviderBeanDefinitionDecorator implements BeanDefinitionDecorator { + @SuppressWarnings("deprecation") public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) { - ConfigUtils.addAuthenticationProvider(parserContext, holder.getBeanName(), (Element) node); + //ConfigUtils.addAuthenticationProvider(parserContext, holder.getBeanName(), (Element) node); + parserContext.getReaderContext().warning(Elements.CUSTOM_AUTH_PROVIDER + " is deprecated in " + + "Spring Security 3.0 and has no effect. Authentication providers should be declared within" + + " the element", parserContext.extractSource(node)); return holder; } diff --git a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java index 978a86fc63..b39de593a7 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java @@ -292,9 +292,13 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { unorderedFilterChain.add(new OrderDecorator(form.filter, AUTHENTICATION_PROCESSING_FILTER)); } + String openIDProviderId = null; + if (openID.filter != null) { unorderedFilterChain.add(new OrderDecorator(openID.filter, OPENID_PROCESSING_FILTER)); - authenticationProviders.add(createOpenIDProvider(element, pc)); + BeanReference openIDProvider = createOpenIDProvider(element, pc); + openIDProviderId = openIDProvider.getBeanName(); + authenticationProviders.add(openIDProvider); } if (loginPageGenerationFilter != null) { @@ -350,7 +354,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { BeanDefinitionBuilder userServiceInjector = BeanDefinitionBuilder.rootBeanDefinition(UserDetailsServiceInjectionBeanPostProcessor.class); userServiceInjector.addConstructorArgValue(x509ProviderId); userServiceInjector.addConstructorArgValue(rememberMeServicesId); - userServiceInjector.addConstructorArgValue(rememberMeServicesId); + userServiceInjector.addConstructorArgValue(openIDProviderId); userServiceInjector.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); pc.getReaderContext().registerWithGeneratedName(userServiceInjector.getBeanDefinition()); diff --git a/config/src/main/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParser.java index 48367785f5..bea6f4cee3 100644 --- a/config/src/main/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParser.java @@ -7,9 +7,7 @@ import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.security.config.BeanIds; import org.springframework.security.config.Elements; -import org.springframework.security.config.authentication.ConfigUtils; import org.springframework.security.config.authentication.PasswordEncoderParser; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; @@ -102,10 +100,7 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser { ldapProvider.addConstructorArgValue(LdapUserServiceBeanDefinitionParser.parseAuthoritiesPopulator(elt, parserContext)); ldapProvider.addPropertyValue("userDetailsContextMapper", LdapUserServiceBeanDefinitionParser.parseUserDetailsClassOrUserMapperRef(elt, parserContext)); - parserContext.getRegistry().registerBeanDefinition(BeanIds.LDAP_AUTHENTICATION_PROVIDER, ldapProvider.getBeanDefinition()); - ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.LDAP_AUTHENTICATION_PROVIDER, elt); - - return null; + return ldapProvider.getBeanDefinition(); } } diff --git a/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java index e0364a884f..0486968ec0 100644 --- a/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java @@ -39,7 +39,6 @@ import org.springframework.security.access.vote.AffirmativeBased; import org.springframework.security.access.vote.AuthenticatedVoter; import org.springframework.security.access.vote.RoleVoter; import org.springframework.security.config.BeanIds; -import org.springframework.security.config.authentication.ConfigUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -74,7 +73,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP @SuppressWarnings("unchecked") public BeanDefinition parse(Element element, ParserContext pc) { - ConfigUtils.registerProviderManagerIfNecessary(pc, element); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)); pc.pushContainingComponent(compositeDef); diff --git a/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java b/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java index 828831caaa..1f90ee935e 100644 --- a/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java +++ b/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java @@ -18,7 +18,6 @@ import org.springframework.security.access.intercept.aopalliance.MethodSecurityI import org.springframework.security.access.method.MapBasedMethodSecurityMetadataSource; import org.springframework.security.config.BeanIds; import org.springframework.security.config.Elements; -import org.springframework.security.config.authentication.ConfigUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -34,7 +33,6 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe private BeanDefinitionDecorator delegate = new InternalInterceptMethodsBeanDefinitionDecorator(); public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { - ConfigUtils.registerProviderManagerIfNecessary(parserContext, (Element) node); MethodConfigUtils.registerDefaultMethodAccessManagerIfNecessary(parserContext); return delegate.decorate(node, definition, parserContext); diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc index 3e91003338..a1b41a74a1 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc @@ -488,24 +488,22 @@ x509.attlist &= user-service-ref? authentication-manager = - ## If you are using namespace configuration with Spring Security, an AuthenticationManager will automatically be registered. This element allows you to define an alias to allow you to reference the authentication-manager in your own beans. - element authentication-manager {authman.attlist} + ## Registers the AuthenticationManager instance and allows its list of AuthenticationProviders to be defined. should use. Also allows you to define an alias to allow you to reference the AuthenticationManager in your own beans. + element authentication-manager {authman.attlist, authentication-provider*, ldap-authentication-provider*} authman.attlist &= ## The alias you wish to use for the AuthenticationManager bean - attribute alias {xsd:ID} + attribute alias {xsd:ID}? authentication-provider = ## Indicates that the contained user-service should be used as an authentication source. element authentication-provider {ap.attlist & any-user-service & password-encoder?} +ap.attlist &= + ## Specifies a reference to a separately configured AuthenticationProvider instance which should be registered within the AuthenticationManager. + ref? ap.attlist &= ## Specifies a reference to a separately configured UserDetailsService from which to obtain authentication data. user-service-ref? -custom-authentication-provider = - ## Element used to decorate an AuthenticationProvider bean to add it to the internal AuthenticationManager maintained by the namespace. - element custom-authentication-provider {cap.attlist} -cap.attlist &= empty - user-service = ## Creates an in-memory UserDetailsService from a properties file or a list of "user" child elements. element user-service {id? & (properties-file | (user*))} diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.xsd index f1f8239581..3316738b0c 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.xsd +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.xsd @@ -1411,17 +1411,21 @@ - If you are using namespace configuration with Spring Security, an - AuthenticationManager will automatically be registered. This element allows you to - define an alias to allow you to reference the authentication-manager in your own beans. - + Registers the AuthenticationManager instance and allows its list of + AuthenticationProviders to be defined. should use. Also allows you to define an alias to + allow you to reference the AuthenticationManager in your own beans. + + + + - + The alias you wish to use for the AuthenticationManager bean @@ -1480,6 +1484,11 @@ + + + Defines a reference to a Spring bean Id. + + A reference to a user-service (or UserDetailsService bean) @@ -1487,13 +1496,6 @@ - - - Element used to decorate an AuthenticationProvider bean to add it to the - internal AuthenticationManager maintained by the namespace. - - - Creates an in-memory UserDetailsService from a properties file or a list diff --git a/config/src/test/java/org/springframework/security/config/ConfigTestUtils.java b/config/src/test/java/org/springframework/security/config/ConfigTestUtils.java index 1ec01f9e9a..92a9740137 100644 --- a/config/src/test/java/org/springframework/security/config/ConfigTestUtils.java +++ b/config/src/test/java/org/springframework/security/config/ConfigTestUtils.java @@ -2,6 +2,7 @@ package org.springframework.security.config; public abstract class ConfigTestUtils { public static final String AUTH_PROVIDER_XML = + "" + " " + " " + " " + @@ -9,5 +10,6 @@ public abstract class ConfigTestUtils { " " + " " + " " + - " "; + " " + + ""; } diff --git a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java index 95d8b7670b..793a592642 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java @@ -1,17 +1,12 @@ package org.springframework.security.config.authentication; -import static org.junit.Assert.assertFalse; - import org.junit.Test; import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException; import org.springframework.context.support.AbstractXmlApplicationContext; -import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl; import org.springframework.security.authentication.concurrent.SessionRegistryImpl; import org.springframework.security.config.BeanIds; -import org.springframework.security.config.ConfigTestUtils; import org.springframework.security.config.util.InMemoryXmlApplicationContext; -import org.springframework.security.util.FieldUtils; /** * @@ -28,24 +23,16 @@ public class AuthenticationManagerBeanDefinitionParserTests { " " + ""; - @Test - public void sessionControllerRefAttributeIsSupportedFor204ContextButHasNoEffect() throws Exception { - setContext( - "" + - SESSION_CONTROLLER + - "" + - ConfigTestUtils.AUTH_PROVIDER_XML, "2.0.4"); - ProviderManager pm = (ProviderManager) appContext.getBean(BeanIds.AUTHENTICATION_MANAGER); - assertFalse(FieldUtils.getFieldValue(pm, "sessionController") instanceof ConcurrentSessionControllerImpl); - } - @Test(expected=XmlBeanDefinitionStoreException.class) public void sessionControllerRefAttributeIsRejectedFor30Context() throws Exception { setContext( - "" + - SESSION_CONTROLLER + - "" + - ConfigTestUtils.AUTH_PROVIDER_XML, "3.0"); + "" + + " " + + " " + + " " + + " " + + " " + + "" + SESSION_CONTROLLER, "3.0"); appContext.getBean(BeanIds.AUTHENTICATION_MANAGER); } diff --git a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParserTests.java index 30ec1830ac..f0c8fe6d67 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParserTests.java @@ -47,7 +47,10 @@ public class AuthenticationProviderBeanDefinitionParserTests { @Test public void externalUserServiceRefWorks() throws Exception { - setContext(" " + + appContext = new InMemoryXmlApplicationContext( + " " + + " " + + " " + " " + " " + " "); @@ -105,11 +108,14 @@ public class AuthenticationProviderBeanDefinitionParserTests { @Test public void externalUserServicePasswordEncoderAndSaltSourceWork() throws Exception { - setContext(" " + + appContext = new InMemoryXmlApplicationContext( + " " + + " " + " " + " " + " " + - " " + + " " + + " " + " " + @@ -132,6 +138,6 @@ public class AuthenticationProviderBeanDefinitionParserTests { } private void setContext(String context) { - appContext = new InMemoryXmlApplicationContext(context); + appContext = new InMemoryXmlApplicationContext("" + context + ""); } } diff --git a/config/src/test/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecoratorTests.java b/config/src/test/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecoratorTests.java index 2ee8a5b331..86dabac1c3 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecoratorTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/CustomAuthenticationProviderBeanDefinitionDecoratorTests.java @@ -1,45 +1,20 @@ package org.springframework.security.config.authentication; -import static org.junit.Assert.*; - import org.junit.Test; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.config.BeanIds; import org.springframework.security.config.util.InMemoryXmlApplicationContext; public class CustomAuthenticationProviderBeanDefinitionDecoratorTests { @Test - public void decoratedProviderParsesSuccessfully() { - InMemoryXmlApplicationContext ctx = new InMemoryXmlApplicationContext( + public void decoratedProviderParsesSuccessfullyWith20Namespace() { + new InMemoryXmlApplicationContext( "" + " " + " " + - "" + + "" + "" + " " + - "" - ); - ProviderManager authMgr = (ProviderManager) ctx.getBean(BeanIds.AUTHENTICATION_MANAGER); - assertEquals(1, authMgr.getProviders().size()); - } - - - @Test - public void decoratedBeanAndRegisteredProviderAreTheSameObject() { - InMemoryXmlApplicationContext ctx = new InMemoryXmlApplicationContext( - "" + - " " + - " " + - "" + - "" + - " " + - "" - ); - - ProviderManager authMgr = (ProviderManager) ctx.getBean(BeanIds.AUTHENTICATION_MANAGER); - assertEquals(1, authMgr.getProviders().size()); - assertSame(ctx.getBean("myProvider"), authMgr.getProviders().get(0)); + "", "2.0.4", null); } } diff --git a/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java index d9d452f132..3521881fae 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/JdbcUserServiceBeanDefinitionParserTests.java @@ -102,9 +102,11 @@ public class JdbcUserServiceBeanDefinitionParserTests { @Test public void isSupportedByAuthenticationProviderElement() { setContext( - "" + + "" + + " " + " " + - "" + DATA_SOURCE); + " " + + "" + DATA_SOURCE); AuthenticationManager mgr = (AuthenticationManager) appContext.getBean(BeanIds.AUTHENTICATION_MANAGER); mgr.authenticate(new UsernamePasswordAuthenticationToken("rod", "koala")); } @@ -112,9 +114,11 @@ public class JdbcUserServiceBeanDefinitionParserTests { @Test public void cacheIsInjectedIntoAuthenticationProvider() { setContext( - "" + + "" + + " " + " " + - "" + DATA_SOURCE + USER_CACHE_XML); + " " + + "" + 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")); diff --git a/config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java index 8c20f2c75e..86240625d6 100644 --- a/config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java @@ -605,7 +605,6 @@ public class HttpSecurityBeanDefinitionParserTests { @Test(expected=BeanDefinitionParsingException.class) public void useOfExternalConcurrentSessionControllerRequiresSessionRegistryToBeSet() throws Exception { setContext( - "" + "" + " " + "" + @@ -619,7 +618,6 @@ public class HttpSecurityBeanDefinitionParserTests { @Test public void useOfExternalSessionControllerAndRegistryIsWiredCorrectly() throws Exception { setContext( - "" + "" + " " + "" + @@ -756,7 +754,9 @@ public class HttpSecurityBeanDefinitionParserTests { public void httpElementDoesntInterfereWithBeanPostProcessing() { setContext( "" + - "" + + "" + + " " + + "" + "" + "" ); diff --git a/config/src/test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java index c8fab44d40..b7f8ca72b2 100644 --- a/config/src/test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java @@ -43,7 +43,10 @@ public class LdapProviderBeanDefinitionParserTests { @Test public void simpleProviderAuthenticatesCorrectly() { - setContext(" "); + setContext("" + + "" + + " " + + ""); LdapAuthenticationProvider provider = getProvider(); Authentication auth = provider.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword")); @@ -61,9 +64,11 @@ public class LdapProviderBeanDefinitionParserTests { @Test public void supportsPasswordComparisonAuthentication() { setContext(" " + + "" + "" + " " + - ""); + ""+ + ""); LdapAuthenticationProvider provider = getProvider(); provider.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword")); } @@ -72,9 +77,11 @@ public class LdapProviderBeanDefinitionParserTests { @Test public void supportsPasswordComparisonAuthenticationWithHashAttribute() { setContext(" " + + "" + "" + " " + - ""); + "" + + ""); LdapAuthenticationProvider provider = getProvider(); provider.authenticate(new UsernamePasswordAuthenticationToken("ben", "ben")); } @@ -82,11 +89,13 @@ public class LdapProviderBeanDefinitionParserTests { @Test public void supportsPasswordComparisonAuthenticationWithPasswordEncoder() { setContext(" " + + "" + "" + " " + " " + " " + - ""); + "" + + ""); LdapAuthenticationProvider provider = getProvider(); provider.authenticate(new UsernamePasswordAuthenticationToken("ben", "ben")); } @@ -94,14 +103,18 @@ public class LdapProviderBeanDefinitionParserTests { @Test public void detectsNonStandardServerId() { setContext(" " + - ""); + "" + + " " + + ""); } @Test public void inetOrgContextMapperIsSupported() throws Exception { setContext( "" + - ""); + "" + + " " + + ""); LdapAuthenticationProvider provider = getProvider(); assertTrue(FieldUtils.getFieldValue(provider, "userDetailsContextMapper") instanceof InetOrgPersonContextMapper); } diff --git a/config/src/test/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParserTests.java index 687dec9473..72b5804c99 100644 --- a/config/src/test/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParserTests.java @@ -95,7 +95,9 @@ public class GlobalMethodSecurityBeanDefinitionParserTests { setContext( "" + "" + - "" + + "" + + " " + + "" + "" ); @@ -113,7 +115,9 @@ public class GlobalMethodSecurityBeanDefinitionParserTests { "" + "" + "" + - "" + "" + + " " + + "" ); UserDetailsService service = (UserDetailsService) appContext.getBean("myUserService"); diff --git a/config/src/test/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecoratorTests.java b/config/src/test/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecoratorTests.java index 0c7f860e0e..c58f56ea92 100644 --- a/config/src/test/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecoratorTests.java +++ b/config/src/test/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecoratorTests.java @@ -22,7 +22,6 @@ import org.springframework.security.core.context.SecurityContextHolder; */ public class InterceptMethodsBeanDefinitionDecoratorTests { private ClassPathXmlApplicationContext appContext; - private TestBusinessBean target; @Before @@ -50,13 +49,9 @@ public class InterceptMethodsBeanDefinitionDecoratorTests { target.unprotected(); } - @Test + @Test(expected=AuthenticationCredentialsNotFoundException.class) public void targetShouldPreventProtectedMethodInvocationWithNoContext() { - try { - target.doSomething(); - fail("Expected AuthenticationCredentialsNotFoundException"); - } catch (AuthenticationCredentialsNotFoundException expected) { - } + target.doSomething(); } @Test @@ -65,20 +60,16 @@ public class InterceptMethodsBeanDefinitionDecoratorTests { AuthorityUtils.createAuthorityList("ROLE_USER")); SecurityContextHolder.getContext().setAuthentication(token); - target.doSomething(); } - @Test + @Test(expected=AccessDeniedException.class) public void targetShouldPreventProtectedMethodInvocationWithIncorrectRole() { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", AuthorityUtils.createAuthorityList("ROLE_SOMEOTHERROLE")); SecurityContextHolder.getContext().setAuthentication(token); - try { - target.doSomething(); - fail("Expected AccessDeniedException"); - } catch (AccessDeniedException expected) { - } + target.doSomething(); + fail("Expected AccessDeniedException"); } } diff --git a/config/src/test/java/org/springframework/security/intercept/method/aopalliance/MethodSecurityInterceptorWithAopConfigTests.java b/config/src/test/java/org/springframework/security/intercept/method/aopalliance/MethodSecurityInterceptorWithAopConfigTests.java index 8fe50b00e4..a4648554a5 100644 --- a/config/src/test/java/org/springframework/security/intercept/method/aopalliance/MethodSecurityInterceptorWithAopConfigTests.java +++ b/config/src/test/java/org/springframework/security/intercept/method/aopalliance/MethodSecurityInterceptorWithAopConfigTests.java @@ -19,12 +19,14 @@ import org.springframework.security.core.context.SecurityContextHolder; */ public class MethodSecurityInterceptorWithAopConfigTests { static final String AUTH_PROVIDER_XML = + "" + " " + " " + " " + " " + " " + - " "; + " " + + ""; static final String ACCESS_MANAGER_XML = "" + diff --git a/core/src/test/resources/org/springframework/security/config/method-security.xml b/config/src/test/resources/org/springframework/security/config/method-security.xml similarity index 66% rename from core/src/test/resources/org/springframework/security/config/method-security.xml rename to config/src/test/resources/org/springframework/security/config/method-security.xml index ae9ca1b966..a5ab42ef73 100644 --- a/core/src/test/resources/org/springframework/security/config/method-security.xml +++ b/config/src/test/resources/org/springframework/security/config/method-security.xml @@ -4,7 +4,7 @@ xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd -http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> +http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> @@ -15,11 +15,13 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc - - - - - - + + + + + + + + - \ No newline at end of file + diff --git a/core/src/test/resources/org/springframework/security/config/users.properties b/config/src/test/resources/org/springframework/security/config/users.properties similarity index 100% rename from core/src/test/resources/org/springframework/security/config/users.properties rename to config/src/test/resources/org/springframework/security/config/users.properties diff --git a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml index dc7e2272a7..f172a8a896 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -34,10 +34,12 @@ - - - - + + + + + + diff --git a/samples/contacts/src/test/resources/applicationContext-contacts-test.xml b/samples/contacts/src/test/resources/applicationContext-contacts-test.xml index 5ec0ed0eba..6ba00ab109 100644 --- a/samples/contacts/src/test/resources/applicationContext-contacts-test.xml +++ b/samples/contacts/src/test/resources/applicationContext-contacts-test.xml @@ -17,10 +17,12 @@ - - - - + + + + + + diff --git a/samples/openid/pom.xml b/samples/openid/pom.xml index 0add842659..08e0f790b4 100644 --- a/samples/openid/pom.xml +++ b/samples/openid/pom.xml @@ -15,6 +15,16 @@ spring-security-core ${project.version} + + org.springframework.security + spring-security-config + ${project.version} + + + org.springframework.security + spring-security-web + ${project.version} + org.springframework.security spring-security-openid @@ -40,14 +50,14 @@ spring-aop runtime - - javax.servlet - jstl - - - taglibs - standard - + + javax.servlet + jstl + + + taglibs + standard + @@ -63,4 +73,4 @@ - \ No newline at end of file + diff --git a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml index 4d7532d276..4851f04567 100644 --- a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -10,33 +10,17 @@ xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd - http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd"> + http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> - + - - diff --git a/samples/preauth/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/preauth/src/main/webapp/WEB-INF/applicationContext-security.xml index 4e72628f05..ec0defb214 100644 --- a/samples/preauth/src/main/webapp/WEB-INF/applicationContext-security.xml +++ b/samples/preauth/src/main/webapp/WEB-INF/applicationContext-security.xml @@ -20,11 +20,12 @@ - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + +