diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java index e5c41496cd..bed550efa9 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java @@ -43,7 +43,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { public static final String LOGOUT_ELEMENT = "logout"; public static final String FORM_LOGIN_ELEMENT = "form-login"; public static final String BASIC_AUTH_ELEMENT = "http-basic"; - public static final String REMEMBER_ME_ELEMENT = "remember-me"; + public static final String REMEMBER_ME_ELEMENT = "remember-me"; static final String PATH_PATTERN_ATTRIBUTE = "pattern"; static final String PATTERN_TYPE_ATTRIBUTE = "pathType"; @@ -100,8 +100,15 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext); } + // Parse remember me before logout as RememberMeServices is also a LogoutHandler implementation. BeanDefinitionRegistry registry = parserContext.getRegistry(); + Element rememberMeElt = DomUtils.getChildElementByTagName(element, REMEMBER_ME_ELEMENT); + + if (rememberMeElt != null) { + new RememberMeBeanDefinitionParser().parse(rememberMeElt, parserContext); + } + Element logoutElt = DomUtils.getChildElementByTagName(element, LOGOUT_ELEMENT); if (logoutElt != null) { @@ -120,12 +127,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { new BasicAuthenticationBeanDefinitionParser().parse(basicAuthElt, parserContext); } - Element rememberMeElt = DomUtils.getChildElementByTagName(element, REMEMBER_ME_ELEMENT); - - if (rememberMeElt != null) { - new RememberMeBeanDefinitionParser().parse(rememberMeElt, parserContext); - } - registry.registerBeanDefinition(DEFAULT_FILTER_CHAIN_PROXY_ID, filterChainProxy); registry.registerBeanDefinition(DEFAULT_HTTP_SESSION_FILTER_ID, httpSCIF); registry.registerBeanDefinition(DEFAULT_EXCEPTION_TRANSLATION_FILTER_ID, diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java index b2452027a8..3e254f26a5 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java @@ -1,7 +1,11 @@ package org.springframework.security.config; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.springframework.security.concurrent.ConcurrentSessionFilter; +import org.springframework.security.context.HttpSessionContextIntegrationFilter; +import org.springframework.security.ui.AbstractProcessingFilter; +import org.springframework.security.ui.AuthenticationEntryPoint; +import org.springframework.security.ui.rememberme.RememberMeServices; +import org.springframework.security.util.FilterChainProxy; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; @@ -9,14 +13,11 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; -import org.springframework.security.concurrent.ConcurrentSessionFilter; -import org.springframework.security.context.HttpSessionContextIntegrationFilter; -import org.springframework.security.ui.AbstractProcessingFilter; -import org.springframework.security.ui.AuthenticationEntryPoint; -import org.springframework.security.ui.rememberme.RememberMeServices; -import org.springframework.security.util.FilterChainProxy; import org.springframework.util.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import javax.servlet.Filter; import java.util.ArrayList; import java.util.Collections; @@ -45,21 +46,17 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor configureAuthenticationEntryPoint(beanFactory); - configureAuthenticationFilter(beanFactory); + configureAuthenticationFilter(beanFactory); configureFilterChain(beanFactory); } private void configureRememberMeSerices(ConfigurableListableBeanFactory beanFactory) { - try { + try { BeanDefinition rememberMeServices = beanFactory.getBeanDefinition(RememberMeBeanDefinitionParser.DEFAULT_REMEMBER_ME_SERVICES_ID); rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService", ConfigUtils.getUserDetailsService(beanFactory)); - - BeanDefinition logoutFilter = - beanFactory.getBeanDefinition(HttpSecurityBeanDefinitionParser.DEFAULT_FILTER_SECURITY_INTERCEPTOR_ID); - } catch (NoSuchBeanDefinitionException e) { // ignore } diff --git a/core/src/main/java/org/springframework/security/config/LogoutBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/LogoutBeanDefinitionParser.java index bd7ec5c00a..7c8134cbf5 100644 --- a/core/src/main/java/org/springframework/security/config/LogoutBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/LogoutBeanDefinitionParser.java @@ -1,14 +1,16 @@ package org.springframework.security.config; +import org.springframework.security.ui.logout.LogoutFilter; +import org.springframework.security.ui.logout.SecurityContextLogoutHandler; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.BeanDefinitionStoreException; -import org.springframework.security.ui.logout.LogoutFilter; -import org.springframework.security.ui.logout.LogoutHandler; -import org.springframework.security.ui.logout.SecurityContextLogoutHandler; import org.springframework.util.StringUtils; + import org.w3c.dom.Element; /** @@ -22,7 +24,7 @@ public class LogoutBeanDefinitionParser extends AbstractSingleBeanDefinitionPars return LogoutFilter.class; } - protected void doParse(Element element, BeanDefinitionBuilder builder) { + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String logoutUrl = element.getAttribute("logoutUrl"); if (StringUtils.hasText(logoutUrl)) { @@ -36,7 +38,15 @@ public class LogoutBeanDefinitionParser extends AbstractSingleBeanDefinitionPars } builder.addConstructorArg(logoutSuccessUrl); - builder.addConstructorArg(new LogoutHandler[] {new SecurityContextLogoutHandler()}); + ManagedList handlers = new ManagedList(); + handlers.add(new SecurityContextLogoutHandler()); + + if (parserContext.getRegistry().containsBeanDefinition(RememberMeBeanDefinitionParser.DEFAULT_REMEMBER_ME_SERVICES_ID)) { + handlers.add(new RuntimeBeanReference(RememberMeBeanDefinitionParser.DEFAULT_REMEMBER_ME_SERVICES_ID)); + } + + builder.addConstructorArg(handlers); + } protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {