mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-03-06 05:19:15 +00:00
SEC-792: Filters should only be added to the default stack if they are labelled using custom-filter.
http://jira.springframework.org/browse/SEC-792. The filters are now maintained as a list in the context and have to be stored there explicitly on registration.
This commit is contained in:
parent
80cd7f4acc
commit
38774ec94f
@ -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.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
@ -70,6 +71,7 @@ public class AnonymousBeanDefinitionParser implements BeanDefinitionParser {
|
||||
authMgrProviderList.add(provider);
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_PROCESSING_FILTER, filter);
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.ANONYMOUS_PROCESSING_FILTER));
|
||||
parserContext.registerComponent(new BeanComponentDefinition(filter, BeanIds.ANONYMOUS_PROCESSING_FILTER));
|
||||
|
||||
return null;
|
||||
|
@ -41,6 +41,7 @@ public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionPa
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_FILTER,
|
||||
filterBuilder.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.BASIC_AUTHENTICATION_FILTER));
|
||||
parserContext.registerComponent(new BeanComponentDefinition(filterBuilder.getBeanDefinition(),
|
||||
BeanIds.BASIC_AUTHENTICATION_FILTER));
|
||||
return null;
|
||||
|
@ -18,6 +18,7 @@ public abstract class BeanIds {
|
||||
static final String CONTEXT_SOURCE_SETTING_POST_PROCESSOR = "_contextSettingPostProcessor";
|
||||
static final String HTTP_POST_PROCESSOR = "_httpConfigBeanFactoryPostProcessor";
|
||||
static final String FILTER_CHAIN_POST_PROCESSOR = "_filterChainProxyPostProcessor";
|
||||
static final String FILTER_LIST = "_filterChainList";
|
||||
|
||||
public static final String JDBC_USER_DETAILS_MANAGER = "_jdbcUserDetailsManager";
|
||||
public static final String USER_DETAILS_SERVICE = "_userDetailsService";
|
||||
|
@ -83,6 +83,7 @@ public class ConcurrentSessionsBeanDefinitionParser implements BeanDefinitionPar
|
||||
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));
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.CONCURRENT_SESSION_FILTER));
|
||||
|
||||
BeanDefinition providerManager = ConfigUtils.registerProviderManagerIfNecessary(parserContext);
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
package org.springframework.security.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
@ -83,7 +87,6 @@ public abstract class ConfigUtils {
|
||||
return authManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains a user details service for use in RememberMeServices etc. Will return a caching version
|
||||
* if available so should not be used for beans which need to separate the two.
|
||||
@ -110,4 +113,50 @@ public abstract class ConfigUtils {
|
||||
BeanDefinition authManager = registerProviderManagerIfNecessary(parserContext);
|
||||
return (ManagedList) authManager.getPropertyValues().getPropertyValue("providers").getValue();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean which holds the list of filters which are maintained in the context and modified by calls to
|
||||
* addHttpFilter. The post processor retrieves these before injecting the list into the FilterChainProxy.
|
||||
*/
|
||||
public static class FilterChainList {
|
||||
List filters;
|
||||
|
||||
public List getFilters() {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public void setFilters(List filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,9 @@ package org.springframework.security.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@ -16,9 +13,8 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.security.config.ConfigUtils.FilterChainList;
|
||||
import org.springframework.security.util.FilterChainProxy;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,70 +25,33 @@ import org.springframework.util.Assert;
|
||||
public class FilterChainProxyPostProcessor implements BeanPostProcessor, BeanFactoryAware {
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if(!beanName.equals(BeanIds.FILTER_CHAIN_PROXY)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
FilterChainProxy filterChainProxy = (FilterChainProxy) bean;
|
||||
// Set the default match
|
||||
List defaultFilterChain = orderFilters(beanFactory);
|
||||
|
||||
FilterChainList filterList = (FilterChainList) beanFactory.getBean(BeanIds.FILTER_LIST);
|
||||
|
||||
List filters = new ArrayList(filterList.getFilters());
|
||||
Collections.sort(filters, new OrderComparator());
|
||||
// Note that this returns a copy
|
||||
Map filterMap = filterChainProxy.getFilterChainMap();
|
||||
String allUrlsMatch = filterChainProxy.getMatcher().getUniversalMatchPattern();
|
||||
|
||||
filterMap.put(allUrlsMatch, defaultFilterChain);
|
||||
filterMap.put(filterChainProxy.getMatcher().getUniversalMatchPattern(), filters);
|
||||
filterChainProxy.setFilterChainMap(filterMap);
|
||||
|
||||
logger.info("Configured filter chain(s): " + filterChainProxy);
|
||||
logger.info("FilterChainProxy: " + filterChainProxy);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private List orderFilters(ListableBeanFactory beanFactory) {
|
||||
Map filters = beanFactory.getBeansOfType(Filter.class);
|
||||
|
||||
Assert.notEmpty(filters, "No filters found in app context!");
|
||||
|
||||
Iterator ids = filters.keySet().iterator();
|
||||
|
||||
List orderedFilters = new ArrayList();
|
||||
|
||||
while (ids.hasNext()) {
|
||||
String id = (String) ids.next();
|
||||
Filter filter = (Filter) filters.get(id);
|
||||
|
||||
if (filter instanceof FilterChainProxy) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filters must be Spring security filters or wrapped using <custom-filter>
|
||||
if (!filter.getClass().getName().startsWith("org.springframework.security")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(filter instanceof Ordered)) {
|
||||
logger.info("Filter " + id + " doesn't implement the Ordered interface, skipping it.");
|
||||
continue;
|
||||
}
|
||||
|
||||
orderedFilters.add(filter);
|
||||
}
|
||||
|
||||
Collections.sort(orderedFilters, new OrderComparator());
|
||||
|
||||
return orderedFilters;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = (ListableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = (ListableBeanFactory) beanFactory;
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
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) {
|
||||
ConfigUtils.registerProviderManagerIfNecessary(parserContext);
|
||||
@ -117,9 +116,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
parseInterceptUrlsForChannelSecurityAndFilterChain(interceptUrlElts, filterChainMap, channelRequestMap,
|
||||
convertPathsToLowerCase, parserContext);
|
||||
|
||||
registerHttpSessionIntegrationFilter(element, registry);
|
||||
registerHttpSessionIntegrationFilter(element, parserContext);
|
||||
|
||||
registerServletApiFilter(element, registry);
|
||||
registerServletApiFilter(element, parserContext);
|
||||
|
||||
// Set up the access manager reference for http
|
||||
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
|
||||
@ -134,15 +133,15 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
DomUtils.getChildElementByTagName(element, Elements.PORT_MAPPINGS), parserContext);
|
||||
registry.registerBeanDefinition(BeanIds.PORT_MAPPER, portMapper);
|
||||
|
||||
registerExceptionTranslationFilter(element.getAttribute(ATT_ACCESS_DENIED_PAGE), registry);
|
||||
registerExceptionTranslationFilter(element.getAttribute(ATT_ACCESS_DENIED_PAGE), parserContext);
|
||||
|
||||
|
||||
if (channelRequestMap.size() > 0) {
|
||||
// At least one channel requirement has been specified
|
||||
registerChannelProcessingBeans(parserContext.getRegistry(), matcher, channelRequestMap);
|
||||
registerChannelProcessingBeans(parserContext, matcher, channelRequestMap);
|
||||
}
|
||||
|
||||
registerFilterSecurityInterceptor(element, registry, matcher, accessManagerId,
|
||||
registerFilterSecurityInterceptor(element, parserContext, matcher, accessManagerId,
|
||||
parseInterceptUrlsForFilterInvocationRequestMap(interceptUrlElts, convertPathsToLowerCase, parserContext));
|
||||
|
||||
boolean sessionControlEnabled = registerConcurrentSessionControlBeansIfRequired(element, parserContext);
|
||||
@ -200,15 +199,10 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
filterChainProxy.getPropertyValues().addPropertyValue("matcher", matcher);
|
||||
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy);
|
||||
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
|
||||
// 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);
|
||||
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
}
|
||||
|
||||
private void registerHttpSessionIntegrationFilter(Element element, BeanDefinitionRegistry registry) {
|
||||
private void registerHttpSessionIntegrationFilter(Element element, ParserContext pc) {
|
||||
RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
|
||||
|
||||
String createSession = element.getAttribute(ATT_CREATE_SESSION);
|
||||
@ -224,19 +218,21 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
|
||||
}
|
||||
|
||||
registry.registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER));
|
||||
}
|
||||
|
||||
// Adds the servlet-api integration filter if required
|
||||
private void registerServletApiFilter(Element element, BeanDefinitionRegistry registry) {
|
||||
private void registerServletApiFilter(Element element, ParserContext pc) {
|
||||
String provideServletApi = element.getAttribute(ATT_SERVLET_API_PROVISION);
|
||||
if (!StringUtils.hasText(provideServletApi)) {
|
||||
provideServletApi = DEF_SERVLET_API_PROVISION;
|
||||
}
|
||||
|
||||
if ("true".equals(provideServletApi)) {
|
||||
registry.registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER,
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER,
|
||||
new RootBeanDefinition(SecurityContextHolderAwareRequestFilter.class));
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER));
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +249,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void registerExceptionTranslationFilter(String accessDeniedPage, BeanDefinitionRegistry registry) {
|
||||
private void registerExceptionTranslationFilter(String accessDeniedPage, ParserContext pc) {
|
||||
BeanDefinitionBuilder exceptionTranslationFilterBuilder
|
||||
= BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class);
|
||||
|
||||
@ -263,10 +259,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
exceptionTranslationFilterBuilder.addPropertyValue("accessDeniedHandler", accessDeniedHandler);
|
||||
}
|
||||
|
||||
registry.registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition());
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.EXCEPTION_TRANSLATION_FILTER));
|
||||
}
|
||||
|
||||
private void registerFilterSecurityInterceptor(Element element, BeanDefinitionRegistry registry, UrlMatcher matcher,
|
||||
private void registerFilterSecurityInterceptor(Element element, ParserContext pc, UrlMatcher matcher,
|
||||
String accessManagerId, LinkedHashMap filterInvocationDefinitionMap) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);
|
||||
|
||||
@ -279,10 +276,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
builder.addPropertyValue("objectDefinitionSource",
|
||||
new DefaultFilterInvocationDefinitionSource(matcher, filterInvocationDefinitionMap));
|
||||
registry.registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, builder.getBeanDefinition());
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, builder.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FILTER_SECURITY_INTERCEPTOR));
|
||||
}
|
||||
|
||||
private void registerChannelProcessingBeans(BeanDefinitionRegistry registry, UrlMatcher matcher, LinkedHashMap channelRequestMap) {
|
||||
private void registerChannelProcessingBeans(ParserContext pc, UrlMatcher matcher, LinkedHashMap channelRequestMap) {
|
||||
RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class);
|
||||
channelFilter.getPropertyValues().addPropertyValue("channelDecisionManager",
|
||||
new RuntimeBeanReference(BeanIds.CHANNEL_DECISION_MANAGER));
|
||||
@ -307,11 +305,13 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
channelProcessors.add(inSecureChannelProcessor);
|
||||
channelDecisionManager.getPropertyValues().addPropertyValue("channelProcessors", channelProcessors);
|
||||
|
||||
registry.registerBeanDefinition(BeanIds.CHANNEL_PROCESSING_FILTER, channelFilter);
|
||||
registry.registerBeanDefinition(BeanIds.CHANNEL_DECISION_MANAGER, channelDecisionManager);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.CHANNEL_PROCESSING_FILTER, channelFilter);
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.CHANNEL_PROCESSING_FILTER));
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.CHANNEL_DECISION_MANAGER, channelDecisionManager);
|
||||
|
||||
}
|
||||
|
||||
private void registerSessionFixationProtectionFilter(ParserContext parserContext, String sessionFixationAttribute, boolean sessionControlEnabled) {
|
||||
private void registerSessionFixationProtectionFilter(ParserContext pc, String sessionFixationAttribute, boolean sessionControlEnabled) {
|
||||
if(!StringUtils.hasText(sessionFixationAttribute)) {
|
||||
sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;
|
||||
}
|
||||
@ -324,13 +324,14 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
if (sessionControlEnabled) {
|
||||
sessionFixationFilter.addPropertyReference("sessionRegistry", BeanIds.SESSION_REGISTRY);
|
||||
}
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER,
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER,
|
||||
sessionFixationFilter.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SESSION_FIXATION_PROTECTION_FILTER));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void parseBasicFormLoginAndOpenID(Element element, ParserContext parserContext, boolean autoConfig) {
|
||||
private void parseBasicFormLoginAndOpenID(Element element, ParserContext pc, boolean autoConfig) {
|
||||
RootBeanDefinition formLoginFilter = null;
|
||||
RootBeanDefinition formLoginEntryPoint = null;
|
||||
String formLoginPage = null;
|
||||
@ -345,7 +346,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
|
||||
if (basicAuthElt != null || autoConfig) {
|
||||
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext);
|
||||
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, pc);
|
||||
}
|
||||
|
||||
Element formLoginElt = DomUtils.getChildElementByTagName(element, Elements.FORM_LOGIN);
|
||||
@ -354,7 +355,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_security_check",
|
||||
"org.springframework.security.ui.webapp.AuthenticationProcessingFilter");
|
||||
|
||||
parser.parse(formLoginElt, parserContext);
|
||||
parser.parse(formLoginElt, pc);
|
||||
formLoginFilter = parser.getFilterBean();
|
||||
formLoginEntryPoint = parser.getEntryPointBean();
|
||||
formLoginPage = parser.getLoginPage();
|
||||
@ -366,7 +367,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_openid_security_check",
|
||||
"org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter");
|
||||
|
||||
parser.parse(openIDLoginElt, parserContext);
|
||||
parser.parse(openIDLoginElt, pc);
|
||||
openIDFilter = parser.getFilterBean();
|
||||
openIDEntryPoint = parser.getEntryPointBean();
|
||||
openIDLoginPage = parser.getLoginPage();
|
||||
@ -381,23 +382,25 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
BeanDefinition openIDProvider = openIDProviderBuilder.getBeanDefinition();
|
||||
ConfigUtils.getRegisteredProviders(parserContext).add(openIDProvider);
|
||||
ConfigUtils.getRegisteredProviders(pc).add(openIDProvider);
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_PROVIDER, openIDProvider);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_PROVIDER, openIDProvider);
|
||||
}
|
||||
|
||||
boolean needLoginPage = false;
|
||||
|
||||
if (formLoginFilter != null) {
|
||||
needLoginPage = true;
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, formLoginFilter);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, formLoginEntryPoint);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, formLoginFilter);
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, formLoginEntryPoint);
|
||||
}
|
||||
|
||||
if (openIDFilter != null) {
|
||||
needLoginPage = true;
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openIDFilter);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openIDEntryPoint);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openIDFilter);
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openIDEntryPoint);
|
||||
}
|
||||
|
||||
// If no login page has been defined, add in the default page generator.
|
||||
@ -415,8 +418,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
loginPageFilter.addConstructorArg(new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
|
||||
}
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER,
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER,
|
||||
loginPageFilter.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER));
|
||||
}
|
||||
|
||||
// We need to establish the main entry point.
|
||||
@ -424,39 +428,39 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
String customEntryPoint = element.getAttribute(ATT_ENTRY_POINT_REF);
|
||||
|
||||
if (StringUtils.hasText(customEntryPoint)) {
|
||||
parserContext.getRegistry().registerAlias(customEntryPoint, BeanIds.MAIN_ENTRY_POINT);
|
||||
pc.getRegistry().registerAlias(customEntryPoint, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// Basic takes precedence if explicit element is used and no others are configured
|
||||
if (basicAuthElt != null && formLoginElt == null && openIDLoginElt == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
pc.getRegistry().registerAlias(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// If formLogin has been enabled either through an element or auto-config, then it is used if no openID login page
|
||||
// has been set
|
||||
if (formLoginFilter != null && openIDLoginPage == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.FORM_LOGIN_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
pc.getRegistry().registerAlias(BeanIds.FORM_LOGIN_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise use OpenID if enabled
|
||||
if (openIDFilter != null && formLoginFilter == null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.OPEN_ID_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
pc.getRegistry().registerAlias(BeanIds.OPEN_ID_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
// If X.509 has been enabled, use the preauth entry point.
|
||||
if (DomUtils.getChildElementByTagName(element, Elements.X509) != null) {
|
||||
parserContext.getRegistry().registerAlias(BeanIds.PRE_AUTH_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
pc.getRegistry().registerAlias(BeanIds.PRE_AUTH_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
|
||||
return;
|
||||
}
|
||||
|
||||
parserContext.getReaderContext().error("No AuthenticationEntryPoint could be established. Please " +
|
||||
pc.getReaderContext().error("No AuthenticationEntryPoint could be established. Please " +
|
||||
"make sure you have a login mechanism configured through the namespace (such as form-login) or " +
|
||||
"specify a custom AuthenticationEntryPoint with the custom-entry-point-ref attribute ",
|
||||
parserContext.extractSource(element));
|
||||
pc.extractSource(element));
|
||||
}
|
||||
|
||||
static UrlMatcher createUrlMatcher(Element element) {
|
||||
|
@ -70,7 +70,8 @@ public class LogoutBeanDefinitionParser implements BeanDefinitionParser {
|
||||
builder.addConstructorArg(handlers);
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.LOGOUT_FILTER, builder.getBeanDefinition());
|
||||
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.LOGOUT_FILTER));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
@ -22,8 +22,8 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Replaces a Spring bean of type "Filter" with a wrapper class which implements the <tt>Ordered</tt>
|
||||
* interface. This allows user to add their own filter to the security chain. If the user's filter
|
||||
* Adds the decorated "Filter" bean into the standard filter chain maintained by the FilterChainProxy.
|
||||
* This allows user to add their own custom filters to the security chain. If the user's filter
|
||||
* already implements Ordered, and no "order" attribute is specified, the filter's default order will be used.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
@ -39,16 +39,17 @@ public class OrderedFilterBeanDefinitionDecorator implements BeanDefinitionDecor
|
||||
Element elt = (Element)node;
|
||||
String order = getOrder(elt, parserContext);
|
||||
|
||||
BeanDefinition filter = holder.getBeanDefinition();
|
||||
BeanDefinitionBuilder wrapper = BeanDefinitionBuilder.rootBeanDefinition("org.springframework.security.config.OrderedFilterBeanDefinitionDecorator$OrderedFilterDecorator");
|
||||
wrapper.addConstructorArg(holder.getBeanName());
|
||||
wrapper.addConstructorArg(filter);
|
||||
wrapper.addConstructorArg(new RuntimeBeanReference(holder.getBeanName()));
|
||||
|
||||
if (StringUtils.hasText(order)) {
|
||||
wrapper.addPropertyValue("order", order);
|
||||
}
|
||||
|
||||
return new BeanDefinitionHolder(wrapper.getBeanDefinition(), holder.getBeanName());
|
||||
ConfigUtils.addHttpFilter(parserContext, wrapper.getBeanDefinition());
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,5 +124,9 @@ public class OrderedFilterBeanDefinitionDecorator implements BeanDefinitionDecor
|
||||
public String toString() {
|
||||
return "OrderedFilterDecorator[ delegate=" + delegate + "; order=" + getOrder() + "]";
|
||||
}
|
||||
|
||||
Filter getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES, services);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_FILTER, filter);
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.REMEMBER_ME_FILTER));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ public class X509BeanDefinitionParser implements BeanDefinitionParser {
|
||||
filterBuilder.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_FILTER, filterBuilder.getBeanDefinition());
|
||||
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.X509_FILTER));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -259,7 +259,8 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||
|
||||
@Test
|
||||
public void externalFiltersAreTreatedCorrectly() throws Exception {
|
||||
// Decorated user-filter should be added to stack. The other one should be ignored
|
||||
// Decorated user-filter should be added to stack. The other MockFilter and the un-decorated standard filter
|
||||
// should be ignored
|
||||
setContext(
|
||||
"<http auto-config='true'/>" + AUTH_PROVIDER_XML +
|
||||
"<b:bean id='userFilter' class='org.springframework.security.util.MockFilter'>" +
|
||||
@ -268,7 +269,9 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||
"<b:bean id='userFilter2' class='org.springframework.security.util.MockFilter'>" +
|
||||
" <custom-filter position='FIRST'/>" +
|
||||
"</b:bean>" +
|
||||
"<b:bean id='userFilter3' class='org.springframework.security.util.MockFilter'/>");
|
||||
"<b:bean id='userFilter3' class='org.springframework.security.util.MockFilter'/>" +
|
||||
"<b:bean id='userFilter4' class='org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter'/>"
|
||||
);
|
||||
List filters = getFilters("/someurl");
|
||||
|
||||
assertEquals(13, filters.size());
|
||||
|
Loading…
x
Reference in New Issue
Block a user