mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-03-09 06:50:05 +00:00
SEC-909: custom remember me services doesn't get registered as logout handler
http://jira.springframework.org/browse/SEC-909. HttpSecurityBeanDefinitionParser now passes the resolved RememberMeServices bean name to the LogoutBeanDefinitionparser so that it an use it explicitly.
This commit is contained in:
parent
1ddc033fe5
commit
f453264bde
@ -159,20 +159,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
new AnonymousBeanDefinitionParser().parse(anonymousElt, parserContext);
|
||||
}
|
||||
|
||||
// Parse remember me before logout as RememberMeServices is also a LogoutHandler implementation.
|
||||
Element rememberMeElt = DomUtils.getChildElementByTagName(element, Elements.REMEMBER_ME);
|
||||
if (rememberMeElt != null || autoConfig) {
|
||||
new RememberMeBeanDefinitionParser().parse(rememberMeElt, parserContext);
|
||||
// Post processor to inject RememberMeServices into filters which need it
|
||||
RootBeanDefinition rememberMeInjectionPostProcessor = new RootBeanDefinition(RememberMeServicesInjectionBeanPostProcessor.class);
|
||||
rememberMeInjectionPostProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR, rememberMeInjectionPostProcessor);
|
||||
}
|
||||
|
||||
Element logoutElt = DomUtils.getChildElementByTagName(element, Elements.LOGOUT);
|
||||
if (logoutElt != null || autoConfig) {
|
||||
new LogoutBeanDefinitionParser().parse(logoutElt, parserContext);
|
||||
}
|
||||
parseRememberMeAndLogout(element, autoConfig, parserContext);
|
||||
|
||||
parseBasicFormLoginAndOpenID(element, parserContext, autoConfig, allowSessionCreation);
|
||||
|
||||
@ -192,6 +179,27 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void parseRememberMeAndLogout(Element elt, boolean autoConfig, ParserContext pc) {
|
||||
// Parse remember me before logout as RememberMeServices is also a LogoutHandler implementation.
|
||||
Element rememberMeElt = DomUtils.getChildElementByTagName(elt, Elements.REMEMBER_ME);
|
||||
String rememberMeServices = null;
|
||||
|
||||
if (rememberMeElt != null || autoConfig) {
|
||||
RememberMeBeanDefinitionParser rmbdp = new RememberMeBeanDefinitionParser();
|
||||
rmbdp.parse(rememberMeElt, pc);
|
||||
rememberMeServices = rmbdp.getServicesName();
|
||||
// Post processor to inject RememberMeServices into filters which need it
|
||||
RootBeanDefinition rememberMeInjectionPostProcessor = new RootBeanDefinition(RememberMeServicesInjectionBeanPostProcessor.class);
|
||||
rememberMeInjectionPostProcessor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES_INJECTION_POST_PROCESSOR, rememberMeInjectionPostProcessor);
|
||||
}
|
||||
|
||||
Element logoutElt = DomUtils.getChildElementByTagName(elt, Elements.LOGOUT);
|
||||
if (logoutElt != null || autoConfig) {
|
||||
new LogoutBeanDefinitionParser(rememberMeServices).parse(logoutElt, pc);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFilterChainProxy(ParserContext pc, Map filterChainMap, UrlMatcher matcher, Object source) {
|
||||
if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
|
||||
pc.getReaderContext().error("Duplicate <http> element detected", source);
|
||||
|
@ -25,6 +25,12 @@ public class LogoutBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
static final String ATT_LOGOUT_URL = "logout-url";
|
||||
static final String DEF_LOGOUT_URL = "/j_spring_security_logout";
|
||||
|
||||
String rememberMeServices;
|
||||
|
||||
public LogoutBeanDefinitionParser(String rememberMeServices) {
|
||||
this.rememberMeServices = rememberMeServices;
|
||||
}
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String logoutUrl = null;
|
||||
@ -66,8 +72,8 @@ public class LogoutBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
handlers.add(sclh);
|
||||
|
||||
if (parserContext.getRegistry().containsBeanDefinition(BeanIds.REMEMBER_ME_SERVICES)) {
|
||||
handlers.add(new RuntimeBeanReference(BeanIds.REMEMBER_ME_SERVICES));
|
||||
if (rememberMeServices != null) {
|
||||
handlers.add(new RuntimeBeanReference(rememberMeServices));
|
||||
}
|
||||
|
||||
builder.addConstructorArg(handlers);
|
||||
|
@ -32,6 +32,7 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
|
||||
static final String ATT_TOKEN_VALIDITY = "token-validity-seconds";
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
private String servicesName;
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String tokenRepository = null;
|
||||
@ -102,8 +103,10 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
services.setSource(source);
|
||||
services.getPropertyValues().addPropertyValue(ATT_KEY, key);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES, services);
|
||||
parserContext.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES, services);
|
||||
servicesName = BeanIds.REMEMBER_ME_SERVICES;
|
||||
} else {
|
||||
servicesName = rememberMeServicesRef;
|
||||
parserContext.getRegistry().registerAlias(rememberMeServicesRef, BeanIds.REMEMBER_ME_SERVICES);
|
||||
}
|
||||
|
||||
@ -114,7 +117,11 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void registerProvider(ParserContext pc, Object source, String key) {
|
||||
String getServicesName() {
|
||||
return servicesName;
|
||||
}
|
||||
|
||||
private void registerProvider(ParserContext pc, Object source, String key) {
|
||||
BeanDefinition authManager = ConfigUtils.registerProviderManagerIfNecessary(pc);
|
||||
RootBeanDefinition provider = new RootBeanDefinition(RememberMeAuthenticationProvider.class);
|
||||
provider.setSource(source);
|
||||
|
@ -51,7 +51,8 @@ public class RememberMeServicesInjectionBeanPostProcessor implements BeanPostPro
|
||||
Map beans = beanFactory.getBeansOfType(RememberMeServices.class);
|
||||
|
||||
Assert.isTrue(beans.size() > 0, "No RememberMeServices configured");
|
||||
Assert.isTrue(beans.size() == 1, "More than one RememberMeServices bean found.");
|
||||
Assert.isTrue(beans.size() == 1, "Use of '<remember-me />' requires a single instance of RememberMeServices " +
|
||||
"in the application context, but more than one was found.");
|
||||
|
||||
return (RememberMeServices) beans.values().toArray()[0];
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import org.springframework.security.ui.SessionFixationProtectionFilter;
|
||||
import org.springframework.security.ui.WebAuthenticationDetails;
|
||||
import org.springframework.security.ui.basicauth.BasicProcessingFilter;
|
||||
import org.springframework.security.ui.logout.LogoutFilter;
|
||||
import org.springframework.security.ui.logout.LogoutHandler;
|
||||
import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter;
|
||||
import org.springframework.security.ui.rememberme.NullRememberMeServices;
|
||||
import org.springframework.security.ui.rememberme.PersistentTokenBasedRememberMeServices;
|
||||
@ -378,7 +379,11 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||
AUTH_PROVIDER_XML);
|
||||
|
||||
assertEquals(5000, FieldUtils.getFieldValue(appContext.getBean(BeanIds.REMEMBER_ME_SERVICES),
|
||||
"tokenValiditySeconds"));
|
||||
"tokenValiditySeconds"));
|
||||
// SEC-909
|
||||
LogoutHandler[] logoutHandlers = (LogoutHandler[]) FieldUtils.getFieldValue(appContext.getBean(BeanIds.LOGOUT_FILTER), "handlers");
|
||||
assertEquals(2, logoutHandlers.length);
|
||||
assertEquals(appContext.getBean(BeanIds.REMEMBER_ME_SERVICES), logoutHandlers[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user