From 8d7830a1ee9cf9ddce88cbcb593ca92dd74b2e16 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Thu, 6 Jan 2011 15:16:13 +0000 Subject: [PATCH] SEC-1603: Add support in namespace for use of AuthenticationSuccessHandler with remember-me. --- .../http/RememberMeBeanDefinitionParser.java | 24 +++++++++++-------- .../security/config/spring-security-3.1.rnc | 5 ++++ .../security/config/spring-security-3.1.xsd | 5 ++++ .../config/http/RememberMeConfigTests.groovy | 13 ++++++++++ .../manual/src/docbook/appendix-namespace.xml | 7 ++++++ 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java index 966ed7625f..cd751e6f67 100644 --- a/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java @@ -28,11 +28,11 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser { static final String ATT_SERVICES_ALIAS = "services-alias"; static final String ATT_TOKEN_REPOSITORY = "token-repository-ref"; static final String ATT_USER_SERVICE_REF = "user-service-ref"; + static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref"; static final String ATT_TOKEN_VALIDITY = "token-validity-seconds"; static final String ATT_SECURE_COOKIE = "use-secure-cookie"; protected final Log logger = LogFactory.getLog(getClass()); - private String servicesName; private final String key; RememberMeBeanDefinitionParser(String key) { @@ -47,6 +47,7 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser { String tokenRepository = element.getAttribute(ATT_TOKEN_REPOSITORY); String dataSource = element.getAttribute(ATT_DATA_SOURCE); String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF); + String successHandlerRef = element.getAttribute(ATT_SUCCESS_HANDLER_REF); String rememberMeServicesRef = element.getAttribute(ATT_SERVICES_REF); String tokenValiditySeconds = element.getAttribute(ATT_TOKEN_VALIDITY); Object source = pc.extractSource(element); @@ -87,6 +88,8 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser { services = new RootBeanDefinition(TokenBasedRememberMeServices.class); } + String servicesName; + if (services != null) { RootBeanDefinition uds = new RootBeanDefinition(); uds.setFactoryBeanName(BeanIds.USER_DETAILS_SERVICE_FACTORY); @@ -100,8 +103,8 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser { } if (tokenValiditySet) { - Integer tokenValidity = Integer.valueOf(tokenValiditySeconds); - if (tokenValidity.intValue() < 0 && isPersistent) { + int tokenValidity = Integer.parseInt(tokenValiditySeconds); + if (tokenValidity < 0 && isPersistent) { pc.getReaderContext().error(ATT_TOKEN_VALIDITY + " cannot be negative if using" + " a persistent remember-me token repository", source); } @@ -119,17 +122,18 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser { pc.getRegistry().registerAlias(servicesName, element.getAttribute(ATT_SERVICES_ALIAS)); } - BeanDefinition filter = createFilter(pc, source); - pc.popAndRegisterContainingComponent(); - - return filter; - } - - private BeanDefinition createFilter(ParserContext pc, Object source) { BeanDefinitionBuilder filter = BeanDefinitionBuilder.rootBeanDefinition(RememberMeAuthenticationFilter.class); filter.getRawBeanDefinition().setSource(source); + + if (StringUtils.hasText(successHandlerRef)) { + filter.addPropertyReference("authenticationSuccessHandler", successHandlerRef); + } + filter.addPropertyReference("rememberMeServices", servicesName); + pc.popAndRegisterContainingComponent(); + return filter.getBeanDefinition(); } + } diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc index e622d4b391..b59a7d3f2f 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.1.rnc @@ -535,6 +535,11 @@ remember-me.attlist &= ## The period (in seconds) for which the remember-me cookie should be valid. attribute token-validity-seconds {xsd:integer}? +remember-me.attlist &= + ## Reference to an AuthenticationSuccessHandler bean which should be used to handle a successful remember-me authentication. + attribute authentication-success-handler-ref {xsd:token}? + + token-repository-ref = ## Reference to a PersistentTokenRepository bean for use with the persistent token remember-me implementation. attribute token-repository-ref {xsd:token} diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd index c8b1434f13..1bac12711c 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd @@ -1166,6 +1166,11 @@ The period (in seconds) for which the remember-me cookie should be valid. + + + Reference to an AuthenticationSuccessHandler bean which should be used to handle a successful remember-me authentication. + + diff --git a/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy index 35764c8680..998b2fe954 100644 --- a/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy @@ -13,6 +13,7 @@ import org.springframework.security.web.authentication.rememberme.PersistentToke import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices import static org.springframework.security.config.ConfigTestUtils.AUTH_PROVIDER_XML +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler /** * @@ -45,6 +46,18 @@ class RememberMeConfigTests extends AbstractHttpConfigTests { rememberMeServices() instanceof PersistentTokenBasedRememberMeServices } + def rememberMeServiceWorksWithAuthenticationSuccessHandlerRef() { + httpAutoConfig () { + 'remember-me'('authentication-success-handler-ref': 'sh') + } + bean('sh', SimpleUrlAuthenticationSuccessHandler.class.name, ['/target']) + + createAppContext(AUTH_PROVIDER_XML) + + expect: + getFilter(RememberMeAuthenticationFilter.class).successHandler instanceof SimpleUrlAuthenticationSuccessHandler + } + def rememberMeServiceWorksWithExternalServicesImpl() { httpAutoConfig () { 'remember-me'('key': "#{'our' + 'key'}", 'services-ref': 'rms') diff --git a/docs/manual/src/docbook/appendix-namespace.xml b/docs/manual/src/docbook/appendix-namespace.xml index 449a8892b0..a83180b7df 100644 --- a/docs/manual/src/docbook/appendix-namespace.xml +++ b/docs/manual/src/docbook/appendix-namespace.xml @@ -369,6 +369,13 @@ and used automatically by the namespace configuration. If there are multiple instances, you can specify a bean id explicitly using this attribute. +
+ <literal>authentication-success-handler-ref</literal> + Sets the authenticationSuccessHandler property on the + RememberMeAuthenticationFilter if custom navigation is required. + The value should be the name of a AuthenticationSuccessHandler + bean in the application context. +
The <literal><session-management></literal> Element