From b3366a164625032118f82eb2991bdb51fcd8db91 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Wed, 8 Jul 2009 16:19:26 +0000 Subject: [PATCH] SEC-1186: Tidying up changes to http parsing --- ...enticationManagerBeanDefinitionParser.java | 2 +- ...sicAuthenticationBeanDefinitionParser.java | 44 ---- .../security/config/BeanIds.java | 16 +- .../security/config/ConfigUtils.java | 34 ---- .../EntryPointInjectionBeanPostProcessor.java | 60 ------ .../config/FilterChainProxyPostProcessor.java | 190 ------------------ .../HttpSecurityBeanDefinitionParser.java | 85 ++------ .../security/config/spring-security-3.0.rnc | 2 +- ...HttpSecurityBeanDefinitionParserTests.java | 11 +- 9 files changed, 31 insertions(+), 413 deletions(-) delete mode 100644 config/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java delete mode 100644 config/src/main/java/org/springframework/security/config/EntryPointInjectionBeanPostProcessor.java delete mode 100644 config/src/main/java/org/springframework/security/config/FilterChainProxyPostProcessor.java diff --git a/config/src/main/java/org/springframework/security/config/AuthenticationManagerBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/AuthenticationManagerBeanDefinitionParser.java index 5d129ba2c2..f4675bdac7 100644 --- a/config/src/main/java/org/springframework/security/config/AuthenticationManagerBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/AuthenticationManagerBeanDefinitionParser.java @@ -42,7 +42,7 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition sessionRegistryInjector.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); sessionRegistryInjector.getConstructorArgumentValues().addGenericArgumentValue(sessionControllerRef); - parserContext.getRegistry().registerBeanDefinition(BeanIds.SESSION_REGISTRY_INJECTION_POST_PROCESSOR, sessionRegistryInjector); + parserContext.getReaderContext().registerWithGeneratedName(sessionRegistryInjector); } parserContext.getRegistry().registerAlias(BeanIds.AUTHENTICATION_MANAGER, alias); diff --git a/config/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java deleted file mode 100644 index fb396f94fc..0000000000 --- a/config/src/main/java/org/springframework/security/config/BasicAuthenticationBeanDefinitionParser.java +++ /dev/null @@ -1,44 +0,0 @@ -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; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.security.web.authentication.www.BasicProcessingFilter; -import org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint; -import org.w3c.dom.Element; - -/** - * Creates a {@link BasicProcessingFilter} and {@link BasicProcessingFilterEntryPoint} and - * registers them in the application context. - * - * @author Luke Taylor - * @author Ben Alex - * @version $Id$ - */ -public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionParser { - private String realmName; - - public BasicAuthenticationBeanDefinitionParser(String realmName) { - this.realmName = realmName; - } - - 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); - - filterBuilder.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); - filterBuilder.addPropertyValue("authenticationEntryPoint", new RuntimeBeanReference(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT)); - - return filterBuilder.getBeanDefinition(); - } -} diff --git a/config/src/main/java/org/springframework/security/config/BeanIds.java b/config/src/main/java/org/springframework/security/config/BeanIds.java index 8f0622c126..1d580d5a8c 100644 --- a/config/src/main/java/org/springframework/security/config/BeanIds.java +++ b/config/src/main/java/org/springframework/security/config/BeanIds.java @@ -17,8 +17,8 @@ public abstract class BeanIds { static final String INTERCEPT_METHODS_BEAN_FACTORY_POST_PROCESSOR = "_interceptMethodsBeanfactoryPP"; static final String CONTEXT_SOURCE_SETTING_POST_PROCESSOR = "_contextSettingPostProcessor"; // static final String ENTRY_POINT_INJECTION_POST_PROCESSOR = "_entryPointInjectionBeanPostProcessor"; - static final String USER_DETAILS_SERVICE_INJECTION_POST_PROCESSOR = "_userServiceInjectionPostProcessor"; - static final String SESSION_REGISTRY_INJECTION_POST_PROCESSOR = "_sessionRegistryInjectionPostProcessor"; +// static final String USER_DETAILS_SERVICE_INJECTION_POST_PROCESSOR = "_userServiceInjectionPostProcessor"; +// static final String SESSION_REGISTRY_INJECTION_POST_PROCESSOR = "_sessionRegistryInjectionPostProcessor"; // static final String FILTER_CHAIN_POST_PROCESSOR = "_filterChainProxyPostProcessor"; // static final String FILTER_LIST = "_filterChainList"; @@ -40,7 +40,7 @@ public abstract class BeanIds { public static final String OPEN_ID_FILTER = "_openIDFilter"; public static final String OPEN_ID_ENTRY_POINT = "_openIDFilterEntryPoint"; public static final String OPEN_ID_PROVIDER = "_openIDAuthenticationProvider"; - public static final String MAIN_ENTRY_POINT = "_mainEntryPoint"; +// public static final String MAIN_ENTRY_POINT = "_mainEntryPoint"; public static final String FILTER_CHAIN_PROXY = "_filterChainProxy"; // public static final String SECURITY_CONTEXT_PERSISTENCE_FILTER = "_securityContextPersistenceFilter"; public static final String LDAP_AUTHENTICATION_PROVIDER = "_ldapAuthenticationProvider"; @@ -57,13 +57,13 @@ public abstract class BeanIds { public static final String SESSION_FIXATION_PROTECTION_FILTER = "_sessionFixationProtectionFilter"; public static final String METHOD_SECURITY_METADATA_SOURCE_ADVISOR = "_methodSecurityMetadataSourceAdvisor"; public static final String PROTECT_POINTCUT_POST_PROCESSOR = "_protectPointcutPostProcessor"; - public static final String SECURED_METHOD_SECURITY_METADATA_SOURCE = "_securedSecurityMetadataSource"; - public static final String JSR_250_METHOD_SECURITY_METADATA_SOURCE = "_jsr250SecurityMetadataSource"; +// public static final String SECURED_METHOD_SECURITY_METADATA_SOURCE = "_securedSecurityMetadataSource"; +// public static final String JSR_250_METHOD_SECURITY_METADATA_SOURCE = "_jsr250SecurityMetadataSource"; public static final String EMBEDDED_APACHE_DS = "_apacheDirectoryServerContainer"; public static final String CONTEXT_SOURCE = "_securityContextSource"; - public static final String PORT_MAPPER = "_portMapper"; +// public static final String PORT_MAPPER = "_portMapper"; // public static final String X509_FILTER = "_x509ProcessingFilter"; public static final String X509_AUTH_PROVIDER = "_x509AuthenticationProvider"; - public static final String PRE_AUTH_ENTRY_POINT = "_preAuthenticatedProcessingFilterEntryPoint"; - public static final String REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR = "_rememberMeServicesInjectionBeanPostProcessor"; +// public static final String PRE_AUTH_ENTRY_POINT = "_preAuthenticatedProcessingFilterEntryPoint"; +// public static final String REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR = "_rememberMeServicesInjectionBeanPostProcessor"; } diff --git a/config/src/main/java/org/springframework/security/config/ConfigUtils.java b/config/src/main/java/org/springframework/security/config/ConfigUtils.java index a92970a7e6..caa1b1c933 100644 --- a/config/src/main/java/org/springframework/security/config/ConfigUtils.java +++ b/config/src/main/java/org/springframework/security/config/ConfigUtils.java @@ -1,7 +1,6 @@ package org.springframework.security.config; import java.util.ArrayList; -import java.util.List; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; @@ -18,7 +17,6 @@ import org.springframework.security.access.vote.AuthenticatedVoter; import org.springframework.security.access.vote.RoleVoter; import org.springframework.security.web.util.UrlUtils; import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** @@ -109,38 +107,6 @@ abstract class ConfigUtils { return manager; } -// private static void registerFilterChainPostProcessorIfNecessary(ParserContext pc) { -// if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_POST_PROCESSOR)) { -// return; -// } -// // Post processor specifically to assemble and order the filter chain immediately before the FilterChainProxy is initialized. -// RootBeanDefinition filterChainPostProcessor = new RootBeanDefinition(FilterChainProxyPostProcessor.class); -// filterChainPostProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); -// pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_POST_PROCESSOR, filterChainPostProcessor); -// RootBeanDefinition filterList = new RootBeanDefinition(FilterChainList.class); -// filterList.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); -// pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_LIST, filterList); -// pc.registerBeanComponent(new BeanComponentDefinition(filterList, BeanIds.FILTER_LIST)); -// } - - // @SuppressWarnings("unchecked") -// static void addHttpFilter(ParserContext pc, BeanMetadataElement filter) { -// registerFilterChainPostProcessorIfNecessary(pc); -// -// RootBeanDefinition filterList = (RootBeanDefinition) pc.getRegistry().getBeanDefinition(BeanIds.FILTER_LIST); -// -// ManagedList filters; -// MutablePropertyValues pvs = filterList.getPropertyValues(); -// if (pvs.contains("filters")) { -// filters = (ManagedList) pvs.getPropertyValue("filters").getValue(); -// } else { -// filters = new ManagedList(); -// pvs.addPropertyValue("filters", filters); -// } -// -// filters.add(filter); -// } - /** * Checks the value of an XML attribute which represents a redirect URL. * If not empty or starting with "$" (potential placeholder), "/" or "http" it will raise an error. diff --git a/config/src/main/java/org/springframework/security/config/EntryPointInjectionBeanPostProcessor.java b/config/src/main/java/org/springframework/security/config/EntryPointInjectionBeanPostProcessor.java deleted file mode 100644 index 6b0986acc9..0000000000 --- a/config/src/main/java/org/springframework/security/config/EntryPointInjectionBeanPostProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.springframework.security.config; - -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.access.ExceptionTranslationFilter; -import org.springframework.util.Assert; - -/** - * - * @author Luke Taylor - * @since 2.0.2 - */ -public class EntryPointInjectionBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { - private final Log logger = LogFactory.getLog(getClass()); - private ConfigurableListableBeanFactory beanFactory; - - @SuppressWarnings("unchecked") - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { -// if (!BeanIds.EXCEPTION_TRANSLATION_FILTER.equals(beanName)) { -// return bean; -// } -// -// logger.info("Selecting AuthenticationEntryPoint for use in ExceptionTranslationFilter"); -// -// ExceptionTranslationFilter etf = (ExceptionTranslationFilter) beanFactory.getBean(BeanIds.EXCEPTION_TRANSLATION_FILTER); -// -// Object entryPoint = null; -// -// if (beanFactory.containsBean(BeanIds.MAIN_ENTRY_POINT)) { -// entryPoint = beanFactory.getBean(BeanIds.MAIN_ENTRY_POINT); -// logger.info("Using main configured AuthenticationEntryPoint."); -// } else { -// Map entryPoints = beanFactory.getBeansOfType(AuthenticationEntryPoint.class); -// Assert.isTrue(entryPoints.size() != 0, "No AuthenticationEntryPoint instances defined"); -// Assert.isTrue(entryPoints.size() == 1, "More than one AuthenticationEntryPoint defined in context"); -// entryPoint = entryPoints.values().toArray()[0]; -// } -// -// logger.info("Using bean '" + entryPoint + "' as the entry point."); -// etf.setAuthenticationEntryPoint((AuthenticationEntryPoint) entryPoint); - - return bean; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; - } -} diff --git a/config/src/main/java/org/springframework/security/config/FilterChainProxyPostProcessor.java b/config/src/main/java/org/springframework/security/config/FilterChainProxyPostProcessor.java deleted file mode 100644 index 37ebc3a389..0000000000 --- a/config/src/main/java/org/springframework/security/config/FilterChainProxyPostProcessor.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.springframework.security.config; - -import java.util.List; - -import javax.servlet.Filter; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.security.web.access.ExceptionTranslationFilter; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.www.BasicProcessingFilter; -import org.springframework.security.web.context.SecurityContextPersistenceFilter; -import org.springframework.security.web.session.SessionFixationProtectionFilter; -import org.springframework.security.web.wrapper.SecurityContextHolderAwareRequestFilter; - -/** - * - * @author Luke Taylor - * @version $Id$ - * @since 2.0 - */ -public class FilterChainProxyPostProcessor implements BeanPostProcessor, BeanFactoryAware { - private Log logger = LogFactory.getLog(getClass()); - - private ListableBeanFactory beanFactory; - - @SuppressWarnings("unchecked") - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { -// if(!BeanIds.FILTER_CHAIN_PROXY.equals(beanName)) { -// return bean; -// } -// -// FilterChainProxy filterChainProxy = (FilterChainProxy) bean; -// FilterChainList filterList = (FilterChainList) beanFactory.getBean(BeanIds.FILTER_LIST); -// -// List filters = new ArrayList(filterList.getFilters()); -// Collections.sort(filters, new OrderComparator()); -// -// logger.info("Checking sorted filter chain: " + filters); -// -// for(int i=0; i < filters.size(); i++) { -// Ordered filter = (Ordered)filters.get(i); -// -// if (i > 0) { -// Ordered previous = (Ordered)filters.get(i-1); -// if (filter.getOrder() == previous.getOrder()) { -// throw new SecurityConfigurationException("Filters '" + unwrapFilter(filter) + "' and '" + -// unwrapFilter(previous) + "' have the same 'order' value. When using custom filters, " + -// "please make sure the positions do not conflict with default filters. " + -// "Alternatively you can disable the default filters by removing the corresponding " + -// "child elements from and avoiding the use of ."); -// } -// } -// } -// -// logger.info("Filter chain..."); -// for (int i=0; i < filters.size(); i++) { -// // Remove the ordered wrapper from the filter and put it back in the chain at the same position. -// Filter filter = unwrapFilter(filters.get(i)); -// logger.info("[" + i + "] - " + filter); -// filters.set(i, filter); -// } -// -// checkFilterStack(filters); -// -// // Note that this returns a copy -// Map> filterMap = filterChainProxy.getFilterChainMap(); -// filterMap.put(filterChainProxy.getMatcher().getUniversalMatchPattern(), filters); -// filterChainProxy.setFilterChainMap(filterMap); -// -// checkLoginPageIsntProtected(filterChainProxy); -// -// logger.info("FilterChainProxy: " + filterChainProxy); - - return bean; - } - - /** - * Checks the filter list for possible errors and logs them - */ - private void checkFilterStack(List filters) { - checkForDuplicates(SecurityContextPersistenceFilter.class, filters); - checkForDuplicates(UsernamePasswordAuthenticationProcessingFilter.class, filters); - checkForDuplicates(SessionFixationProtectionFilter.class, filters); - checkForDuplicates(BasicProcessingFilter.class, filters); - checkForDuplicates(SecurityContextHolderAwareRequestFilter.class, filters); - checkForDuplicates(ExceptionTranslationFilter.class, filters); - checkForDuplicates(FilterSecurityInterceptor.class, filters); - } - - private void checkForDuplicates(Class clazz, List filters) { - for (int i=0; i < filters.size(); i++) { - Filter f1 = filters.get(i); - if (clazz.isAssignableFrom(f1.getClass())) { - // Found the first one, check remaining for another - for (int j=i+1; j < filters.size(); j++) { - Filter f2 = filters.get(j); - if (clazz.isAssignableFrom(f2.getClass())) { - logger.warn("Possible error: Filters at position " + i + " and " + j + " are both " + - "instances of " + clazz.getName()); - return; - } - } - } - } - } - - /* Checks for the common error of having a login page URL protected by the security interceptor */ - private void checkLoginPageIsntProtected(FilterChainProxy fcp) { -// ExceptionTranslationFilter etf = (ExceptionTranslationFilter) beanFactory.getBean(BeanIds.EXCEPTION_TRANSLATION_FILTER); -// -// if (etf.getAuthenticationEntryPoint() instanceof LoginUrlAuthenticationEntryPoint) { -// String loginPage = -// ((LoginUrlAuthenticationEntryPoint)etf.getAuthenticationEntryPoint()).getLoginFormUrl(); -// List filters = fcp.getFilters(loginPage); -// logger.info("Checking whether login URL '" + loginPage + "' is accessible with your configuration"); -// -// if (filters == null || filters.isEmpty()) { -// logger.debug("Filter chain is empty for the login page"); -// return; -// } -// -// if (loginPage.equals(DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL) && -// beanFactory.containsBean(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER)) { -// logger.debug("Default generated login page is in use"); -// return; -// } -// -// FilterSecurityInterceptor fsi = -// ((FilterSecurityInterceptor)beanFactory.getBean(BeanIds.FILTER_SECURITY_INTERCEPTOR)); -// DefaultFilterInvocationSecurityMetadataSource fids = -// (DefaultFilterInvocationSecurityMetadataSource) fsi.getSecurityMetadataSource(); -// List attributes = fids.lookupAttributes(loginPage, "POST"); -// -// if (attributes == null) { -// logger.debug("No access attributes defined for login page URL"); -// if (fsi.isRejectPublicInvocations()) { -// logger.warn("FilterSecurityInterceptor is configured to reject public invocations." + -// " Your login page may not be accessible."); -// } -// return; -// } -// -// if (!beanFactory.containsBean(BeanIds.ANONYMOUS_PROCESSING_FILTER)) { -// logger.warn("The login page is being protected by the filter chain, but you don't appear to have" + -// " anonymous authentication enabled. This is almost certainly an error."); -// return; -// } -// -// // Simulate an anonymous access with the supplied attributes. -// AnonymousProcessingFilter anonPF = (AnonymousProcessingFilter) beanFactory.getBean(BeanIds.ANONYMOUS_PROCESSING_FILTER); -// AnonymousAuthenticationToken token = -// new AnonymousAuthenticationToken("key", anonPF.getUserAttribute().getPassword(), -// anonPF.getUserAttribute().getAuthorities()); -// try { -// fsi.getAccessDecisionManager().decide(token, new Object(), fids.lookupAttributes(loginPage, "POST")); -// } catch (Exception e) { -// logger.warn("Anonymous access to the login page doesn't appear to be enabled. This is almost certainly " + -// "an error. Please check your configuration allows unauthenticated access to the configured " + -// "login page. (Simulated access was rejected: " + e + ")"); -// } -// } - } - - /** - * Returns the delegate filter of a wrapper, or the unchanged filter if it isn't wrapped. - */ - private Filter unwrapFilter(Object filter) { - if (filter instanceof OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator) { - return ((OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator)filter).getDelegate(); - } - - return (Filter) filter; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = (ListableBeanFactory) beanFactory; - } -} diff --git a/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java index 4f9fdaf0f9..356ad7896f 100644 --- a/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java @@ -20,7 +20,6 @@ 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.ManagedList; import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -128,7 +127,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { static final String EXPRESSION_FIMDS_CLASS = "org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource"; static final String EXPRESSION_HANDLER_CLASS = "org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"; - private static final String EXPRESSION_HANDLER_ID = "_webExpressionHandler"; final SecureRandom random; @@ -155,7 +153,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)); pc.pushContainingComponent(compositeDef); - final BeanDefinitionRegistry registry = pc.getRegistry(); final UrlMatcher matcher = createUrlMatcher(element); final Object source = pc.extractSource(element); // SEC-501 - should paths stored in request maps be converted to lower case @@ -194,42 +191,12 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { sessionControlEnabled); BeanDefinition fsi = createFilterSecurityInterceptor(element, pc, matcher, convertPathsToLowerCase); - registry.registerBeanDefinition(BeanIds.PORT_MAPPER, portMapper); + String portMapperName = pc.getReaderContext().registerWithGeneratedName(portMapper); if (channelRequestMap.size() > 0) { // At least one channel requirement has been specified - cpf = createChannelProcessingFilter(pc, matcher, channelRequestMap); + cpf = createChannelProcessingFilter(pc, matcher, channelRequestMap, portMapperName); } -// if (cpf != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.CHANNEL_PROCESSING_FILTER, cpf); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.CHANNEL_PROCESSING_FILTER)); -// } - -// pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER, scpf); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER)); - -// if (anonFilter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_PROCESSING_FILTER, anonFilter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.ANONYMOUS_PROCESSING_FILTER)); -// } -// -// if (servApiFilter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER,servApiFilter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER)); -// } - -// pc.getRegistry().registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, etf); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.EXCEPTION_TRANSLATION_FILTER)); -// - -// pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, fsi); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FILTER_SECURITY_INTERCEPTOR)); - -// if (sessionControlEnabled) { -// pc.getRegistry().registerBeanDefinition(BeanIds.CONCURRENT_SESSION_FILTER, concurrentSessionFilter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.CONCURRENT_SESSION_FILTER)); -// } - if (sfpf != null) { // Used by SessionRegistrynjectionPP pc.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER, sfpf); @@ -249,61 +216,37 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { RootBeanDefinition rememberMeInjectionPostProcessor = new RootBeanDefinition(RememberMeServicesInjectionBeanPostProcessor.class); rememberMeInjectionPostProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR, rememberMeInjectionPostProcessor); + pc.getReaderContext().registerWithGeneratedName(rememberMeInjectionPostProcessor); } final BeanDefinition logoutFilter = createLogoutFilter(element, autoConfig, pc, rememberMeServicesId); -// if (logoutFilter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.LOGOUT_FILTER, logoutFilter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.LOGOUT_FILTER)); -// } - BeanDefinition loginPageGenerationFilter = createLoginPageFilterIfNeeded(form, openID); -// if (basic.filter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_FILTER, basic.filter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.BASIC_AUTHENTICATION_FILTER)); -// } - if (form.filter != null) { // Required by login page filter pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, form.filter); + pc.registerBeanComponent(new BeanComponentDefinition(form.filter, BeanIds.FORM_LOGIN_FILTER)); if (rememberMeServicesId != null) { form.filter.getPropertyValues().addPropertyValue("rememberMeServices", new RuntimeBeanReference(rememberMeServicesId)); } -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER)); -// pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, form.entryPoint); } if (openID.filter != null) { // Required by login page filter pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openID.filter); + pc.registerBeanComponent(new BeanComponentDefinition(openID.filter, BeanIds.OPEN_ID_FILTER)); if (rememberMeServicesId != null) { openID.filter.getPropertyValues().addPropertyValue("rememberMeServices", new RuntimeBeanReference(rememberMeServicesId)); } -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER)); -// pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openID.entryPoint); } -// -// if (loginPageGenerationFilter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER, loginPageGenerationFilter); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER)); -// } FilterAndEntryPoint x509 = createX509Filter(element, pc); -// if (x509.filter != null) { -// pc.getRegistry().registerBeanDefinition(BeanIds.X509_FILTER, x509.filter); -// pc.getRegistry().registerBeanDefinition(BeanIds.PRE_AUTH_ENTRY_POINT, x509.entryPoint); -// ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.X509_FILTER)); -// } BeanMetadataElement entryPoint = selectEntryPoint(element, pc, basic, form, openID, x509); etf.getPropertyValues().addPropertyValue("authenticationEntryPoint", entryPoint); - // Now build the filter chain and add it to the map List unorderedFilterChain = new ArrayList(); -// List filterChain = new ManagedList(); if (cpf != null) { unorderedFilterChain.add(new OrderDecorator(cpf, CHANNEL_FILTER)); @@ -377,14 +320,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { registerFilterChainProxy(pc, filterChainMap, matcher, source); - - // Register the post processors which will tie up the loose ends in the configuration once the app context has been created and all beans are available. -// RootBeanDefinition postProcessor = new RootBeanDefinition(EntryPointInjectionBeanPostProcessor.class); -// postProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); -// registry.registerBeanDefinition(BeanIds.ENTRY_POINT_INJECTION_POST_PROCESSOR, postProcessor); RootBeanDefinition postProcessor2 = new RootBeanDefinition(UserDetailsServiceInjectionBeanPostProcessor.class); postProcessor2.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - registry.registerBeanDefinition(BeanIds.USER_DETAILS_SERVICE_INJECTION_POST_PROCESSOR, postProcessor2); + pc.getReaderContext().registerWithGeneratedName(postProcessor2); pc.popAndRegisterContainingComponent(); return null; @@ -724,9 +662,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { if (StringUtils.hasText(expressionHandlerRef)) { logger.info("Using bean '" + expressionHandlerRef + "' as web SecurityExpressionHandler implementation"); } else { - pc.getRegistry().registerBeanDefinition(EXPRESSION_HANDLER_ID, - BeanDefinitionBuilder.rootBeanDefinition(EXPRESSION_HANDLER_CLASS).getBeanDefinition()); - expressionHandlerRef = EXPRESSION_HANDLER_ID; + BeanDefinition expressionHandler = BeanDefinitionBuilder.rootBeanDefinition(EXPRESSION_HANDLER_CLASS).getBeanDefinition(); + expressionHandlerRef = pc.getReaderContext().registerWithGeneratedName(expressionHandler); + pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef)); } fidsBuilder = BeanDefinitionBuilder.rootBeanDefinition(EXPRESSION_FIMDS_CLASS); @@ -765,7 +703,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { return builder.getBeanDefinition(); } - private BeanDefinition createChannelProcessingFilter(ParserContext pc, UrlMatcher matcher, LinkedHashMap> channelRequestMap) { + private BeanDefinition createChannelProcessingFilter(ParserContext pc, UrlMatcher matcher, + LinkedHashMap> channelRequestMap, String portMapperBeanName) { RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class); channelFilter.getPropertyValues().addPropertyValue("channelDecisionManager", new RuntimeBeanReference(BeanIds.CHANNEL_DECISION_MANAGER)); @@ -779,7 +718,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { RootBeanDefinition secureChannelProcessor = new RootBeanDefinition(SecureChannelProcessor.class); RootBeanDefinition retryWithHttp = new RootBeanDefinition(RetryWithHttpEntryPoint.class); RootBeanDefinition retryWithHttps = new RootBeanDefinition(RetryWithHttpsEntryPoint.class); - RuntimeBeanReference portMapper = new RuntimeBeanReference(BeanIds.PORT_MAPPER); + RuntimeBeanReference portMapper = new RuntimeBeanReference(portMapperBeanName); retryWithHttp.getPropertyValues().addPropertyValue("portMapper", portMapper); retryWithHttps.getPropertyValues().addPropertyValue("portMapper", portMapper); secureChannelProcessor.getPropertyValues().addPropertyValue("entryPoint", retryWithHttps); 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 341a5d5da5..a618a04e26 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 @@ -552,7 +552,7 @@ jdbc-user-service.attlist &= any-user-service = user-service | jdbc-user-service | ldap-user-service custom-filter = - ## 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. + ## Used to indicate that a filter bean declaration should be incorporated into the security filter chain. element custom-filter {custom-filter.attlist} custom-filter.attlist &= diff --git a/config/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java index 9562fd5022..16b07dde41 100644 --- a/config/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java @@ -8,6 +8,8 @@ import static org.springframework.security.config.HttpSecurityBeanDefinitionPars import java.lang.reflect.Method; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.ArrayList; import javax.servlet.Filter; @@ -336,7 +338,7 @@ public class HttpSecurityBeanDefinitionParserTests { " " + " " + AUTH_PROVIDER_XML); - PortMapperImpl pm = (PortMapperImpl) appContext.getBean(BeanIds.PORT_MAPPER); + PortMapperImpl pm = getPortMapper(); assertEquals(1, pm.getTranslatedPortMappings().size()); assertEquals(Integer.valueOf(9080), pm.lookupHttpPort(9443)); assertEquals(Integer.valueOf(9443), pm.lookupHttpsPort(9080)); @@ -354,12 +356,17 @@ public class HttpSecurityBeanDefinitionParserTests { " " + " " + AUTH_PROVIDER_XML); - PortMapperImpl pm = (PortMapperImpl) appContext.getBean(BeanIds.PORT_MAPPER); + PortMapperImpl pm = getPortMapper(); assertEquals(1, pm.getTranslatedPortMappings().size()); assertEquals(Integer.valueOf(9080), pm.lookupHttpPort(9443)); assertEquals(Integer.valueOf(9443), pm.lookupHttpsPort(9080)); } + private PortMapperImpl getPortMapper() { + Map beans = appContext.getBeansOfType(PortMapperImpl.class); + return new ArrayList(beans.values()).get(0); + } + @Test public void accessDeniedPageWorkWithPlaceholders() throws Exception { System.setProperty("accessDenied", "/go-away");