diff --git a/core/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java index 42e39e104f..5d5a78b5e9 100644 --- a/core/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/AnonymousBeanDefinitionParser.java @@ -3,6 +3,7 @@ package org.springframework.security.config; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; @@ -61,6 +62,7 @@ public class AnonymousBeanDefinitionParser implements BeanDefinitionParser { BeanDefinition authManager = ConfigUtils.registerProviderManagerIfNecessary(parserContext); RootBeanDefinition provider = new RootBeanDefinition(AnonymousAuthenticationProvider.class); + provider.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); provider.setSource(source); provider.getPropertyValues().addPropertyValue(ATT_KEY, key); @@ -68,7 +70,8 @@ public class AnonymousBeanDefinitionParser implements BeanDefinitionParser { authMgrProviderList.add(provider); parserContext.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_PROCESSING_FILTER, filter); - + parserContext.registerComponent(new BeanComponentDefinition(filter, BeanIds.ANONYMOUS_PROCESSING_FILTER)); + return null; } } 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 eff2625249..9ae5004994 100644 --- a/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/AuthenticationProviderBeanDefinitionParser.java @@ -6,6 +6,7 @@ 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; @@ -28,6 +29,7 @@ class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser public BeanDefinition parse(Element element, ParserContext parserContext) { RootBeanDefinition authProvider = new RootBeanDefinition(DaoAuthenticationProvider.class); + authProvider.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); authProvider.setSource(parserContext.extractSource(element)); Element passwordEncoderElt = DomUtils.getChildElementByTagName(element, Elements.PASSWORD_ENCODER); @@ -48,7 +50,8 @@ class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser // 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)) { @@ -86,9 +89,11 @@ class AuthenticationProviderBeanDefinitionParser implements BeanDefinitionParser cacheResolverBldr.addConstructorArg(ref); cacheResolverBldr.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); BeanDefinition cacheResolver = cacheResolverBldr.getBeanDefinition(); - parserContext.getRegistry().registerBeanDefinition( - parserContext.getReaderContext().generateBeanName(cacheResolver), cacheResolver); - + + String name = parserContext.getReaderContext().generateBeanName(cacheResolver); + parserContext.getRegistry().registerBeanDefinition(name , cacheResolver); + parserContext.registerComponent(new BeanComponentDefinition(cacheResolver, name)); + ConfigUtils.getRegisteredProviders(parserContext).add(new RuntimeBeanReference(id)); return null; diff --git a/core/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java index ad637122e2..4142361ae4 100644 --- a/core/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java @@ -2,6 +2,7 @@ package org.springframework.security.config; 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.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; @@ -28,7 +29,9 @@ public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionPa public BeanDefinition parse(Element elt, ParserContext parserContext) { BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(BasicProcessingFilter.class); RootBeanDefinition entryPoint = new RootBeanDefinition(BasicProcessingFilterEntryPoint.class); - + entryPoint.setSource(parserContext.extractSource(elt)); + entryPoint.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + entryPoint.getPropertyValues().addPropertyValue("realmName", realmName); parserContext.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, entryPoint); @@ -38,7 +41,8 @@ public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionPa parserContext.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_FILTER, filterBuilder.getBeanDefinition()); - + parserContext.registerComponent(new BeanComponentDefinition(filterBuilder.getBeanDefinition(), + BeanIds.BASIC_AUTHENTICATION_FILTER)); return null; } } diff --git a/core/src/main/java/org/springframework/security/config/ConcurrentSessionsBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/ConcurrentSessionsBeanDefinitionParser.java index 1b8e14104e..b2d85e30c1 100644 --- a/core/src/main/java/org/springframework/security/config/ConcurrentSessionsBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/ConcurrentSessionsBeanDefinitionParser.java @@ -2,6 +2,8 @@ package org.springframework.security.config; 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.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -30,7 +32,11 @@ public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionPar static final String ATT_SESSION_REGISTRY_ALIAS = "session-registry-alias"; public BeanDefinition parse(Element element, ParserContext parserContext) { - BeanDefinitionRegistry beanRegistry = parserContext.getRegistry(); + CompositeComponentDefinition compositeDef = + new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); + parserContext.pushContainingComponent(compositeDef); + + BeanDefinitionRegistry beanRegistry = parserContext.getRegistry(); RootBeanDefinition sessionRegistry = new RootBeanDefinition(SessionRegistryImpl.class); BeanDefinitionBuilder filterBuilder = @@ -42,8 +48,10 @@ public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionPar Object source = parserContext.extractSource(element); filterBuilder.setSource(source); + filterBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); controllerBuilder.setSource(source); - + controllerBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + String expiryUrl = element.getAttribute(ATT_EXPIRY_URL); if (StringUtils.hasText(expiryUrl)) { @@ -64,6 +72,7 @@ public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionPar BeanDefinition controller = controllerBuilder.getBeanDefinition(); beanRegistry.registerBeanDefinition(BeanIds.SESSION_REGISTRY, sessionRegistry); + parserContext.registerComponent(new BeanComponentDefinition(sessionRegistry, BeanIds.SESSION_REGISTRY)); String registryAlias = element.getAttribute(ATT_SESSION_REGISTRY_ALIAS); if (StringUtils.hasText(registryAlias)) { @@ -71,12 +80,16 @@ public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionPar } beanRegistry.registerBeanDefinition(BeanIds.CONCURRENT_SESSION_CONTROLLER, controller); + parserContext.registerComponent(new BeanComponentDefinition(controller, BeanIds.CONCURRENT_SESSION_CONTROLLER)); beanRegistry.registerBeanDefinition(BeanIds.CONCURRENT_SESSION_FILTER, filterBuilder.getBeanDefinition()); - + parserContext.registerComponent(new BeanComponentDefinition(filterBuilder.getBeanDefinition(), BeanIds.CONCURRENT_SESSION_FILTER)); + BeanDefinition providerManager = ConfigUtils.registerProviderManagerIfNecessary(parserContext); providerManager.getPropertyValues().addPropertyValue("sessionController", controller); - + + parserContext.popAndRegisterContainingComponent(); + return null; } } diff --git a/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java index 0f2a2e624a..24f7c7343a 100644 --- a/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java @@ -8,6 +8,7 @@ import java.util.Map; import org.springframework.aop.config.AopNamespaceUtils; 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.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -43,24 +44,26 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser { private static final String ATT_USE_JSR250 = "jsr250-annotations"; private static final String ATT_USE_SECURED = "secured-annotations"; - private void validatePresent(String className) { - Assert.isTrue(ClassUtils.isPresent(className), "Cannot locate '" + className + "'"); + private void validatePresent(String className, Element element, ParserContext parserContext) { + if (!ClassUtils.isPresent(className, parserContext.getReaderContext().getBeanClassLoader())) { + parserContext.getReaderContext().error("Cannot locate '" + className + "'", element); + } } public BeanDefinition parse(Element element, ParserContext parserContext) { - boolean useJsr250 = "enabled".equals(element.getAttribute(ATT_USE_JSR250)); + boolean useJsr250 = "enabled".equals(element.getAttribute(ATT_USE_JSR250)); boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED)); // Check the required classes are present if (useSecured) { - validatePresent(SECURED_METHOD_DEFINITION_SOURCE_CLASS); - validatePresent(SECURED_DEPENDENCY_CLASS); + validatePresent(SECURED_METHOD_DEFINITION_SOURCE_CLASS, element, parserContext); + validatePresent(SECURED_DEPENDENCY_CLASS, element, parserContext); } if (useJsr250) { - validatePresent(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS); - validatePresent(JSR_250_VOTER_CLASS); - validatePresent(JSR_250_DEPENDENCY_CLASS); + validatePresent(JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS, element, parserContext); + validatePresent(JSR_250_VOTER_CLASS, element, parserContext); + validatePresent(JSR_250_DEPENDENCY_CLASS, element, parserContext); } // Now create a Map for each sub-element @@ -84,6 +87,7 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser { if (pointcutMap.size() > 0) { RootBeanDefinition ppbp = new RootBeanDefinition(ProtectPointcutPostProcessor.class); ppbp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + ppbp.setSource(parserContext.extractSource(element)); ppbp.getConstructorArgumentValues().addGenericArgumentValue(mapBasedMethodDefinitionSource); ppbp.getPropertyValues().addPropertyValue("pointcutMap", pointcutMap); parserContext.getRegistry().registerBeanDefinition(BeanIds.PROTECT_POINTCUT_POST_PROCESSOR, ppbp); @@ -104,9 +108,9 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser { // Register our DelegatingMethodDefinitionSource RootBeanDefinition delegatingMethodDefinitionSource = new RootBeanDefinition(DelegatingMethodDefinitionSource.class); delegatingMethodDefinitionSource.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + delegatingMethodDefinitionSource.setSource(parserContext.extractSource(element)); delegatingMethodDefinitionSource.getPropertyValues().addPropertyValue("methodDefinitionSources", delegates); - parserContext.getRegistry().registerBeanDefinition(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE, delegatingMethodDefinitionSource); - + // Register the applicable AccessDecisionManager, handling the special JSR 250 voter if being used String accessManagerId = element.getAttribute(ATT_ACCESS_MGR); @@ -123,20 +127,23 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser { // MethodSecurityInterceptor RootBeanDefinition interceptor = new RootBeanDefinition(MethodSecurityInterceptor.class); interceptor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - + interceptor.setSource(parserContext.extractSource(element)); + interceptor.getPropertyValues().addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId)); interceptor.getPropertyValues().addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); interceptor.getPropertyValues().addPropertyValue("objectDefinitionSource", new RuntimeBeanReference(BeanIds.DELEGATING_METHOD_DEFINITION_SOURCE)); parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_INTERCEPTOR, interceptor); - + parserContext.registerComponent(new BeanComponentDefinition(interceptor, BeanIds.METHOD_SECURITY_INTERCEPTOR)); + // MethodDefinitionSourceAdvisor RootBeanDefinition advisor = new RootBeanDefinition(MethodDefinitionSourceAdvisor.class); advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + advisor.setSource(parserContext.extractSource(element)); advisor.getConstructorArgumentValues().addGenericArgumentValue(interceptor); parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_DEFINITION_SOURCE_ADVISOR, advisor); AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); - + return null; } } 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 e9099e3ca3..1f90aa86ff 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java @@ -29,6 +29,7 @@ import org.springframework.security.securechannel.InsecureChannelProcessor; import org.springframework.security.securechannel.SecureChannelProcessor; import org.springframework.security.securechannel.RetryWithHttpEntryPoint; import org.springframework.security.securechannel.RetryWithHttpsEntryPoint; +import org.springframework.security.ui.AccessDeniedHandlerImpl; import org.springframework.security.ui.ExceptionTranslationFilter; import org.springframework.security.ui.SessionFixationProtectionFilter; import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter; @@ -94,8 +95,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { static final String ATT_USER_SERVICE_REF = "user-service-ref"; static final String ATT_ENTRY_POINT_REF = "entry-point-ref"; - static final String ATT_ONCE_PER_REQUEST = "once-per-request"; + static final String ATT_ACCESS_DENIED_PAGE = "access-denied-page"; + public BeanDefinition parse(Element element, ParserContext parserContext) { BeanDefinitionRegistry registry = parserContext.getRegistry(); @@ -126,6 +128,14 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { BeanDefinitionBuilder exceptionTranslationFilterBuilder = BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class); + + String accessDeniedPage = element.getAttribute(ATT_ACCESS_DENIED_PAGE); + if (StringUtils.hasText(accessDeniedPage)) { + AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl(); + accessDeniedHandler.setErrorPage(accessDeniedPage); + exceptionTranslationFilterBuilder.addPropertyValue("accessDeniedHandler", accessDeniedHandler); + } + Map filterChainMap = new LinkedHashMap(); diff --git a/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java index 2da7b71b97..8f33108bfc 100644 --- a/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/SaltSourceBeanDefinitionParser.java @@ -1,13 +1,12 @@ package org.springframework.security.config; -import org.springframework.security.providers.dao.salt.ReflectionSaltSource; -import org.springframework.security.providers.dao.salt.SystemWideSaltSource; -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.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.security.providers.dao.salt.ReflectionSaltSource; +import org.springframework.security.providers.dao.salt.SystemWideSaltSource; import org.springframework.util.StringUtils; - import org.w3c.dom.Element; /** @@ -27,7 +26,8 @@ public class SaltSourceBeanDefinitionParser implements BeanDefinitionParser { saltSource = new RootBeanDefinition(ReflectionSaltSource.class); saltSource.getPropertyValues().addPropertyValue("userPropertyToUse", userProperty); saltSource.setSource(parserContext.extractSource(element)); - + saltSource.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + return saltSource; } @@ -37,6 +37,7 @@ public class SaltSourceBeanDefinitionParser implements BeanDefinitionParser { saltSource = new RootBeanDefinition(SystemWideSaltSource.class); saltSource.getPropertyValues().addPropertyValue("systemWideSalt", systemWideSalt); saltSource.setSource(parserContext.extractSource(element)); + saltSource.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); return saltSource; }