SEC-1186: Refactoring to bring all filter registrations into the HttpBDP parse method in preparation for building the filter chain and map at that point, rather than in a post-processor

This commit is contained in:
Luke Taylor 2009-06-18 22:33:16 +00:00
parent 44487293f0
commit 074fa7d629
8 changed files with 215 additions and 145 deletions

View File

@ -68,10 +68,6 @@ public class AnonymousBeanDefinitionParser implements BeanDefinitionParser {
parserContext.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_AUTHENTICATION_PROVIDER, provider);
ConfigUtils.addAuthenticationProvider(parserContext, BeanIds.ANONYMOUS_AUTHENTICATION_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;
return filter;
}
}

View File

@ -31,19 +31,14 @@ public class BasicAuthenticationBeanDefinitionParser implements BeanDefinitionPa
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));
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;
return filterBuilder.getBeanDefinition();
}
}

View File

@ -93,14 +93,10 @@ 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));
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.CONCURRENT_SESSION_FILTER));
ConfigUtils.setSessionControllerOnAuthenticationManager(parserContext, BeanIds.CONCURRENT_SESSION_CONTROLLER, element);
parserContext.popAndRegisterContainingComponent();
return null;
return filterBuilder.getBeanDefinition();
}
}

View File

@ -8,6 +8,7 @@ import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
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;
@ -116,6 +117,7 @@ abstract class ConfigUtils {
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")

View File

@ -9,11 +9,15 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
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.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
@ -117,45 +121,60 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
private static final String EXPRESSION_HANDLER_ID = "_webExpressionHandler";
@SuppressWarnings("unchecked")
public BeanDefinition parse(Element element, ParserContext parserContext) {
ConfigUtils.registerProviderManagerIfNecessary(parserContext);
final BeanDefinitionRegistry registry = parserContext.getRegistry();
public BeanDefinition parse(Element element, ParserContext pc) {
ConfigUtils.registerProviderManagerIfNecessary(pc);
final BeanDefinitionRegistry registry = pc.getRegistry();
final UrlMatcher matcher = createUrlMatcher(element);
final Object source = parserContext.extractSource(element);
final Object source = pc.extractSource(element);
// SEC-501 - should paths stored in request maps be converted to lower case
// true if Ant path and using lower case
final boolean convertPathsToLowerCase = (matcher instanceof AntUrlPathMatcher) && matcher.requiresLowerCaseUrl();
final boolean allowSessionCreation = !OPT_CREATE_SESSION_NEVER.equals(element.getAttribute(ATT_CREATE_SESSION));
final List<Element> interceptUrlElts = DomUtils.getChildElementsByTagName(element, Elements.INTERCEPT_URL);
final Map filterChainMap = new LinkedHashMap();
final Map filterChainMap = new ManagedMap();
final LinkedHashMap channelRequestMap = new LinkedHashMap();
registerFilterChainProxy(parserContext, filterChainMap, matcher, source);
registerFilterChainProxy(pc, filterChainMap, matcher, source);
// filterChainMap and channelRequestMap are populated by this call
parseInterceptUrlsForChannelSecurityAndFilterChain(interceptUrlElts, filterChainMap, channelRequestMap,
convertPathsToLowerCase, parserContext);
parseInterceptUrlsForChannelSecurityAndEmptyFilterChains(interceptUrlElts, filterChainMap, channelRequestMap,
convertPathsToLowerCase, pc);
boolean allowSessionCreation = registerSecurityContextPersistenceFilter(element, parserContext);
// Add the default filter list
List filterList = new ManagedList();
filterChainMap.put(matcher.getUniversalMatchPattern(), filterList);
registerServletApiFilter(element, parserContext);
BeanDefinition scpf = createSecurityContextPersistenceFilter(element, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER, scpf);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER));
BeanDefinition servApiFilter = createServletApiFilter(element, pc);
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));
}
// Register the portMapper. A default will always be created, even if no element exists.
BeanDefinition portMapper = new PortMappingsBeanDefinitionParser().parse(
DomUtils.getChildElementByTagName(element, Elements.PORT_MAPPINGS), parserContext);
DomUtils.getChildElementByTagName(element, Elements.PORT_MAPPINGS), pc);
registry.registerBeanDefinition(BeanIds.PORT_MAPPER, portMapper);
registerExceptionTranslationFilter(element, parserContext, allowSessionCreation);
BeanDefinition etf = createExceptionTranslationFilter(element, pc, allowSessionCreation);
pc.getRegistry().registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, etf);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.EXCEPTION_TRANSLATION_FILTER));
if (channelRequestMap.size() > 0) {
// At least one channel requirement has been specified
registerChannelProcessingBeans(parserContext, matcher, channelRequestMap);
BeanDefinition cpf = createChannelProcessingFilter(pc, matcher, channelRequestMap);
pc.getRegistry().registerBeanDefinition(BeanIds.CHANNEL_PROCESSING_FILTER, cpf);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.CHANNEL_PROCESSING_FILTER));
}
boolean useExpressions = "true".equals(element.getAttribute(ATT_USE_EXPRESSIONS));
LinkedHashMap<RequestKey, List<ConfigAttribute>> requestToAttributesMap =
parseInterceptUrlsForFilterInvocationRequestMap(interceptUrlElts, convertPathsToLowerCase, useExpressions, parserContext);
parseInterceptUrlsForFilterInvocationRequestMap(interceptUrlElts, convertPathsToLowerCase, useExpressions, pc);
BeanDefinitionBuilder fidsBuilder;
Class<? extends AccessDecisionVoter>[] voters;
@ -167,7 +186,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (StringUtils.hasText(expressionHandlerRef)) {
logger.info("Using bean '" + expressionHandlerRef + "' as web SecurityExpressionHandler implementation");
} else {
parserContext.getRegistry().registerBeanDefinition(EXPRESSION_HANDLER_ID,
pc.getRegistry().registerBeanDefinition(EXPRESSION_HANDLER_ID,
BeanDefinitionBuilder.rootBeanDefinition(EXPRESSION_HANDLER_CLASS).getBeanDefinition());
expressionHandlerRef = EXPRESSION_HANDLER_ID;
}
@ -189,35 +208,86 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
parserContext.getRegistry().registerBeanDefinition(BeanIds.WEB_ACCESS_MANAGER,
pc.getRegistry().registerBeanDefinition(BeanIds.WEB_ACCESS_MANAGER,
ConfigUtils.createAccessManagerBean(voters));
accessManagerId = BeanIds.WEB_ACCESS_MANAGER;
}
registerFilterSecurityInterceptor(element, parserContext, accessManagerId, fidsBuilder.getBeanDefinition());
BeanDefinition fsi = createFilterSecurityInterceptor(element, pc, accessManagerId, fidsBuilder.getBeanDefinition());
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, fsi);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FILTER_SECURITY_INTERCEPTOR));
boolean sessionControlEnabled = registerConcurrentSessionControlBeansIfRequired(element, parserContext);
boolean sessionControlEnabled = false;
registerSessionFixationProtectionFilter(parserContext, element.getAttribute(ATT_SESSION_FIXATION_PROTECTION),
BeanDefinition concurrentSessionFilter = createConcurrentSessionFilterAndRelatedBeansIfRequired(element, pc);
if (concurrentSessionFilter != null) {
sessionControlEnabled = true;
pc.getRegistry().registerBeanDefinition(BeanIds.CONCURRENT_SESSION_FILTER, concurrentSessionFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.CONCURRENT_SESSION_FILTER));
}
BeanDefinition sfpf = createSessionFixationProtectionFilter(pc, element.getAttribute(ATT_SESSION_FIXATION_PROTECTION),
sessionControlEnabled);
if (sfpf != null) {
pc.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER, sfpf);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SESSION_FIXATION_PROTECTION_FILTER));
}
boolean autoConfig = "true".equals(element.getAttribute(ATT_AUTO_CONFIG));
Element anonymousElt = DomUtils.getChildElementByTagName(element, Elements.ANONYMOUS);
if (anonymousElt == null || !"false".equals(anonymousElt.getAttribute("enabled"))) {
new AnonymousBeanDefinitionParser().parse(anonymousElt, parserContext);
BeanDefinition anonFilter = new AnonymousBeanDefinitionParser().parse(anonymousElt, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.ANONYMOUS_PROCESSING_FILTER, anonFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.ANONYMOUS_PROCESSING_FILTER));
}
parseRememberMeAndLogout(element, autoConfig, parserContext);
parseRememberMeAndLogout(element, autoConfig, pc);
parseBasicFormLoginAndOpenID(element, parserContext, autoConfig, allowSessionCreation);
String realm = element.getAttribute(ATT_REALM);
if (!StringUtils.hasText(realm)) {
realm = DEF_REALM;
}
final FilterAndEntryPoint form = createFormLoginFilter(element, pc, autoConfig, allowSessionCreation);
if (form.filter != null) {
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, form.filter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, form.entryPoint);
}
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
if (basicAuthElt != null || autoConfig) {
BeanDefinition basicFilter = new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.BASIC_AUTHENTICATION_FILTER, basicFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.BASIC_AUTHENTICATION_FILTER));
}
FilterAndEntryPoint openID = createOpenIDLoginFilter(element, pc, autoConfig, allowSessionCreation);
if (openID.filter != null) {
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openID.filter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openID.entryPoint);
}
BeanDefinition loginPageGenerationFilter = createLoginPageFilterIfNeeded(form, openID);
if (loginPageGenerationFilter != null) {
pc.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER, loginPageGenerationFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER));
}
Element x509Elt = DomUtils.getChildElementByTagName(element, Elements.X509);
if (x509Elt != null) {
new X509BeanDefinitionParser().parse(x509Elt, parserContext);
BeanDefinition x509Filter = new X509BeanDefinitionParser().parse(x509Elt, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.X509_FILTER, x509Filter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.X509_FILTER));
}
selectEntryPoint(element, pc, form, openID);
// 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);
@ -236,7 +306,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (rememberMeElt != null) {
RememberMeBeanDefinitionParser rmbdp = new RememberMeBeanDefinitionParser();
rmbdp.parse(rememberMeElt, pc);
BeanDefinition filter = rmbdp.parse(rememberMeElt, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_FILTER, filter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.REMEMBER_ME_FILTER));
rememberMeServices = rmbdp.getServicesName();
// Post processor to inject RememberMeServices into filters which need it
RootBeanDefinition rememberMeInjectionPostProcessor = new RootBeanDefinition(RememberMeServicesInjectionBeanPostProcessor.class);
@ -246,7 +318,10 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
Element logoutElt = DomUtils.getChildElementByTagName(elt, Elements.LOGOUT);
if (logoutElt != null || autoConfig) {
new LogoutBeanDefinitionParser(rememberMeServices).parse(logoutElt, pc);
BeanDefinition logoutFilter = new LogoutBeanDefinitionParser(rememberMeServices).parse(logoutElt, pc);
pc.getRegistry().registerBeanDefinition(BeanIds.LOGOUT_FILTER, logoutFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.LOGOUT_FILTER));
}
}
@ -256,18 +331,19 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
pc.getReaderContext().error("Duplicate <http> element detected", source);
}
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
filterChainProxy.setSource(source);
filterChainProxy.getPropertyValues().addPropertyValue("matcher", matcher);
filterChainProxy.getPropertyValues().addPropertyValue("stripQueryStringFromUrls", Boolean.valueOf(matcher instanceof AntUrlPathMatcher));
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy);
BeanDefinitionBuilder fcpBldr = BeanDefinitionBuilder.rootBeanDefinition(FilterChainProxy.class);
fcpBldr.getRawBeanDefinition().setSource(source);
fcpBldr.addPropertyValue("matcher", matcher);
fcpBldr.addPropertyValue("stripQueryStringFromUrls", Boolean.valueOf(matcher instanceof AntUrlPathMatcher));
fcpBldr.addPropertyValue("filterChainMap", filterChainMap);
BeanDefinition fcpBean = fcpBldr.getBeanDefinition();
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, fcpBean);
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
pc.registerBeanComponent(new BeanComponentDefinition(fcpBean,BeanIds.FILTER_CHAIN_PROXY));
}
private boolean registerSecurityContextPersistenceFilter(Element element, ParserContext pc) {
private BeanDefinition createSecurityContextPersistenceFilter(Element element, ParserContext pc) {
BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class);
boolean sessionCreationAllowed = true;
String repoRef = element.getAttribute(ATT_SECURITY_CONTEXT_REPOSITORY);
String createSession = element.getAttribute(ATT_CREATE_SESSION);
@ -291,7 +367,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
} else if (OPT_CREATE_SESSION_NEVER.equals(createSession)) {
contextRepo.addPropertyValue("allowSessionCreation", Boolean.FALSE);
scpf.addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
sessionCreationAllowed = false;
} else {
createSession = DEF_CREATE_SESSION_IF_REQUIRED;
contextRepo.addPropertyValue("allowSessionCreation", Boolean.TRUE);
@ -305,47 +380,43 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
scpf.addPropertyValue("securityContextRepository", contextRepo.getBeanDefinition());
}
pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER, scpf.getBeanDefinition());
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER));
return sessionCreationAllowed;
return scpf.getBeanDefinition();
}
// Adds the servlet-api integration filter if required
private void registerServletApiFilter(Element element, ParserContext pc) {
private RootBeanDefinition createServletApiFilter(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)) {
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));
return new RootBeanDefinition(SecurityContextHolderAwareRequestFilter.class);
}
return null;
}
private boolean registerConcurrentSessionControlBeansIfRequired(Element element, ParserContext parserContext) {
private BeanDefinition createConcurrentSessionFilterAndRelatedBeansIfRequired(Element element, ParserContext parserContext) {
Element sessionControlElt = DomUtils.getChildElementByTagName(element, Elements.CONCURRENT_SESSIONS);
if (sessionControlElt == null) {
return false;
return null;
}
new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext);
BeanDefinition sessionControlFilter = new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext);
logger.info("Concurrent session filter in use, setting 'forceEagerSessionCreation' to true");
BeanDefinition sessionIntegrationFilter = parserContext.getRegistry().getBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER);
sessionIntegrationFilter.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.TRUE);
return true;
return sessionControlFilter;
}
private void registerExceptionTranslationFilter(Element element, ParserContext pc, boolean allowSessionCreation) {
private BeanDefinition createExceptionTranslationFilter(Element element, ParserContext pc, boolean allowSessionCreation) {
BeanDefinitionBuilder exceptionTranslationFilterBuilder
= BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class);
exceptionTranslationFilterBuilder.addPropertyValue("createSessionAllowed", Boolean.valueOf(allowSessionCreation));
exceptionTranslationFilterBuilder.addPropertyValue("accessDeniedHandler", createAccessDeniedHandler(element, pc));
pc.getRegistry().registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition());
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.EXCEPTION_TRANSLATION_FILTER));
return exceptionTranslationFilterBuilder.getBeanDefinition();
}
private BeanMetadataElement createAccessDeniedHandler(Element element, ParserContext pc) {
@ -384,7 +455,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
return accessDeniedHandler.getBeanDefinition();
}
private void registerFilterSecurityInterceptor(Element element, ParserContext pc, String accessManagerId,
private BeanDefinition createFilterSecurityInterceptor(Element element, ParserContext pc, String accessManagerId,
BeanDefinition fids) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);
@ -396,12 +467,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
}
builder.addPropertyValue("securityMetadataSource", fids);
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, builder.getBeanDefinition());
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FILTER_SECURITY_INTERCEPTOR));
return builder.getBeanDefinition();
}
@SuppressWarnings("unchecked")
private void registerChannelProcessingBeans(ParserContext pc, UrlMatcher matcher, LinkedHashMap channelRequestMap) {
private BeanDefinition createChannelProcessingFilter(ParserContext pc, UrlMatcher matcher, LinkedHashMap channelRequestMap) {
RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class);
channelFilter.getPropertyValues().addPropertyValue("channelDecisionManager",
new RuntimeBeanReference(BeanIds.CHANNEL_DECISION_MANAGER));
@ -425,13 +495,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
channelProcessors.add(inSecureChannelProcessor);
channelDecisionManager.getPropertyValues().addPropertyValue("channelProcessors", channelProcessors);
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);
return channelFilter;
}
private void registerSessionFixationProtectionFilter(ParserContext pc, String sessionFixationAttribute, boolean sessionControlEnabled) {
private BeanDefinition createSessionFixationProtectionFilter(ParserContext pc, String sessionFixationAttribute, boolean sessionControlEnabled) {
if(!StringUtils.hasText(sessionFixationAttribute)) {
sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;
}
@ -444,29 +512,14 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (sessionControlEnabled) {
sessionFixationFilter.addPropertyReference("sessionRegistry", BeanIds.SESSION_REGISTRY);
}
pc.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER,
sessionFixationFilter.getBeanDefinition());
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SESSION_FIXATION_PROTECTION_FILTER));
return sessionFixationFilter.getBeanDefinition();
}
return null;
}
private void parseBasicFormLoginAndOpenID(Element element, ParserContext pc, boolean autoConfig, boolean allowSessionCreation) {
private FilterAndEntryPoint createFormLoginFilter(Element element, ParserContext pc, boolean autoConfig, boolean allowSessionCreation) {
RootBeanDefinition formLoginFilter = null;
RootBeanDefinition formLoginEntryPoint = null;
String formLoginPage = null;
RootBeanDefinition openIDFilter = null;
RootBeanDefinition openIDEntryPoint = null;
String openIDLoginPage = null;
String realm = element.getAttribute(ATT_REALM);
if (!StringUtils.hasText(realm)) {
realm = DEF_REALM;
}
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
if (basicAuthElt != null || autoConfig) {
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, pc);
}
Element formLoginElt = DomUtils.getChildElementByTagName(element, Elements.FORM_LOGIN);
@ -477,10 +530,19 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
parser.parse(formLoginElt, pc);
formLoginFilter = parser.getFilterBean();
formLoginEntryPoint = parser.getEntryPointBean();
formLoginPage = parser.getLoginPage();
}
if (formLoginFilter != null) {
formLoginFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation));
}
return new FilterAndEntryPoint(formLoginFilter, formLoginEntryPoint);
}
private FilterAndEntryPoint createOpenIDLoginFilter(Element element, ParserContext pc, boolean autoConfig, boolean allowSessionCreation) {
Element openIDLoginElt = DomUtils.getChildElementByTagName(element, Elements.OPENID_LOGIN);
RootBeanDefinition openIDFilter = null;
RootBeanDefinition openIDEntryPoint = null;
if (openIDLoginElt != null) {
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_openid_security_check",
@ -489,7 +551,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
parser.parse(openIDLoginElt, pc);
openIDFilter = parser.getFilterBean();
openIDEntryPoint = parser.getEntryPointBean();
openIDLoginPage = parser.getLoginPage();
BeanDefinitionBuilder openIDProviderBuilder =
BeanDefinitionBuilder.rootBeanDefinition(OPEN_ID_AUTHENTICATION_PROVIDER_CLASS);
@ -505,44 +566,24 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
ConfigUtils.addAuthenticationProvider(pc, BeanIds.OPEN_ID_PROVIDER);
}
boolean needLoginPage = false;
if (formLoginFilter != null) {
needLoginPage = true;
formLoginFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation));
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;
openIDFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation));
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.
if (needLoginPage && formLoginPage == null && openIDLoginPage == null) {
logger.info("No login page configured. The default internal one will be used. Use the '"
+ FormLoginBeanDefinitionParser.ATT_LOGIN_PAGE + "' attribute to set the URL of the login page.");
BeanDefinitionBuilder loginPageFilter =
BeanDefinitionBuilder.rootBeanDefinition(DefaultLoginPageGeneratingFilter.class);
return new FilterAndEntryPoint(openIDFilter, openIDEntryPoint);
}
if (formLoginFilter != null) {
loginPageFilter.addConstructorArgValue(new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
}
class FilterAndEntryPoint {
RootBeanDefinition filter;
RootBeanDefinition entryPoint;
if (openIDFilter != null) {
loginPageFilter.addConstructorArgValue(new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
}
pc.getRegistry().registerBeanDefinition(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER,
loginPageFilter.getBeanDefinition());
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.DEFAULT_LOGIN_PAGE_GENERATING_FILTER));
}
public FilterAndEntryPoint(RootBeanDefinition filter, RootBeanDefinition entryPoint) {
this.filter = filter;
this.entryPoint = entryPoint;
}
}
private void selectEntryPoint(Element element, ParserContext pc, FilterAndEntryPoint form, FilterAndEntryPoint openID) {
// We need to establish the main entry point.
// First check if a custom entry point bean is set
String customEntryPoint = element.getAttribute(ATT_ENTRY_POINT_REF);
@ -552,6 +593,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
return;
}
Element basicAuthElt = DomUtils.getChildElementByTagName(element, Elements.BASIC_AUTH);
Element formLoginElt = DomUtils.getChildElementByTagName(element, Elements.FORM_LOGIN);
Element openIDLoginElt = DomUtils.getChildElementByTagName(element, Elements.OPENID_LOGIN);
// Basic takes precedence if explicit element is used and no others are configured
if (basicAuthElt != null && formLoginElt == null && openIDLoginElt == null) {
pc.getRegistry().registerAlias(BeanIds.BASIC_AUTHENTICATION_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
@ -560,13 +604,15 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
// 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) {
String openIDLoginPage = getLoginFormUrl(openID.entryPoint);
if (form.filter != null && openIDLoginPage == null) {
pc.getRegistry().registerAlias(BeanIds.FORM_LOGIN_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
return;
}
// Otherwise use OpenID if enabled
if (openIDFilter != null && formLoginFilter == null) {
if (openID.filter != null && form.filter == null) {
pc.getRegistry().registerAlias(BeanIds.OPEN_ID_ENTRY_POINT, BeanIds.MAIN_ENTRY_POINT);
return;
}
@ -579,10 +625,54 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
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 ",
"specify a custom AuthenticationEntryPoint with the '" + ATT_ENTRY_POINT_REF+ "' attribute ",
pc.extractSource(element));
}
private String getLoginFormUrl(RootBeanDefinition entryPoint) {
if (entryPoint == null) {
return null;
}
PropertyValues pvs = entryPoint.getPropertyValues();
PropertyValue pv = pvs.getPropertyValue("loginFormUrl");
if (pv == null) {
return null;
}
return (String) pv.getValue();
}
BeanDefinition createLoginPageFilterIfNeeded(FilterAndEntryPoint form, FilterAndEntryPoint openID) {
boolean needLoginPage = form.filter != null || openID.filter != null;
String formLoginPage = getLoginFormUrl(form.entryPoint);
// If the login URL is the default one, then it is assumed not to have been set explicitly
if (DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL == formLoginPage) {
formLoginPage = null;
}
String openIDLoginPage = getLoginFormUrl(openID.entryPoint);
// If no login page has been defined, add in the default page generator.
if (needLoginPage && formLoginPage == null && openIDLoginPage == null) {
logger.info("No login page configured. The default internal one will be used. Use the '"
+ FormLoginBeanDefinitionParser.ATT_LOGIN_PAGE + "' attribute to set the URL of the login page.");
BeanDefinitionBuilder loginPageFilter =
BeanDefinitionBuilder.rootBeanDefinition(DefaultLoginPageGeneratingFilter.class);
if (form.filter != null) {
loginPageFilter.addConstructorArgValue(new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
}
if (openID.filter != null) {
loginPageFilter.addConstructorArgValue(new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
}
return loginPageFilter.getBeanDefinition();
}
return null;
}
static UrlMatcher createUrlMatcher(Element element) {
String patternType = element.getAttribute(ATT_PATH_TYPE);
if (!StringUtils.hasText(patternType)) {
@ -625,7 +715,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
* map used to create the FilterInvocationDefintionSource for the FilterSecurityInterceptor.
*/
@SuppressWarnings("unchecked")
void parseInterceptUrlsForChannelSecurityAndFilterChain(List<Element> urlElts, Map filterChainMap, Map channelRequestMap,
void parseInterceptUrlsForChannelSecurityAndEmptyFilterChains(List<Element> urlElts, Map filterChainMap, Map channelRequestMap,
boolean useLowerCasePaths, ParserContext parserContext) {
ConfigAttributeEditor editor = new ConfigAttributeEditor();

View File

@ -79,9 +79,6 @@ public class LogoutBeanDefinitionParser implements BeanDefinitionParser {
builder.addConstructorArgValue(handlers);
parserContext.getRegistry().registerBeanDefinition(BeanIds.LOGOUT_FILTER, builder.getBeanDefinition());
ConfigUtils.addHttpFilter(parserContext, new RuntimeBeanReference(BeanIds.LOGOUT_FILTER));
return null;
return builder.getBeanDefinition();
}
}

View File

@ -116,9 +116,7 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
registerProvider(parserContext, source, key);
registerFilter(parserContext, source);
return null;
return createFilter(parserContext, source);
}
String getServicesName() {
@ -134,7 +132,7 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
ConfigUtils.addAuthenticationProvider(pc, BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER);
}
private void registerFilter(ParserContext pc, Object source) {
private BeanDefinition createFilter(ParserContext pc, Object source) {
RootBeanDefinition filter = new RootBeanDefinition(RememberMeProcessingFilter.class);
filter.setSource(source);
filter.getPropertyValues().addPropertyValue("authenticationManager",
@ -143,7 +141,6 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
filter.getPropertyValues().addPropertyValue("rememberMeServices",
new RuntimeBeanReference(BeanIds.REMEMBER_ME_SERVICES));
pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_FILTER, filter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.REMEMBER_ME_FILTER));
return filter;
}
}

View File

@ -61,9 +61,6 @@ 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;
return filterBuilder.getBeanDefinition();
}
}