瀏覽代碼

SEC-1603: Add support in namespace for use of AuthenticationSuccessHandler with remember-me.

Luke Taylor 14 年之前
父節點
當前提交
8d7830a1ee

+ 14 - 10
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();
     }
+
 }

+ 5 - 0
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}

+ 5 - 0
config/src/main/resources/org/springframework/security/config/spring-security-3.1.xsd

@@ -1166,6 +1166,11 @@
         <xs:documentation>The period (in seconds) for which the remember-me cookie should be valid.</xs:documentation>
       </xs:annotation>
     </xs:attribute>
+    <xs:attribute name="authentication-success-handler-ref" type="xs:token">
+      <xs:annotation>
+        <xs:documentation>Reference to an AuthenticationSuccessHandler bean which should be used to handle a successful remember-me authentication.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
   </xs:attributeGroup>
   <xs:attributeGroup name="token-repository-ref">
     <xs:attribute name="token-repository-ref" use="required" type="xs:token">

+ 13 - 0
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')

+ 7 - 0
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 <literal>id</literal> explicitly using this attribute. </para>
             </section>
+            <section>
+                <title><literal>authentication-success-handler-ref</literal></title>
+                <para>Sets the <code>authenticationSuccessHandler</code> property on the
+                    <classname>RememberMeAuthenticationFilter</classname> if custom navigation is required.
+                    The value should be the name of a <interfacename>AuthenticationSuccessHandler</interfacename>
+                    bean in the application context. </para>
+            </section>
         </section>
         <section xml:id="nsa-session-mgmt">
             <title>The <literal>&lt;session-management&gt;</literal> Element</title>