Browse Source

OPEN - issue SEC-763: Allow setting of alwaysUseDirectTargetUrl via form-login namespace URL
http://jira.springframework.org/browse/SEC-763. Added always-use-default target attribute to namespace.

Luke Taylor 17 years ago
parent
commit
7145198e5a

+ 11 - 2
core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java

@@ -28,6 +28,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
     static final String DEF_LOGIN_PAGE = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL;
 
     static final String ATT_FORM_LOGIN_TARGET_URL = "default-target-url";
+    static final String ATT_ALWAYS_USE_DEFAULT_TARGET_URL = "always-use-default-target";    
     static final String DEF_FORM_LOGIN_TARGET_URL = "/";
 
     static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = "authentication-failure-url";
@@ -49,6 +50,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
         String loginUrl = null;
         String defaultTargetUrl = null;
         String authenticationFailureUrl = null;
+        String alwaysUseDefault = null;
         
         Object source = null;
 
@@ -56,6 +58,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
             loginUrl = elt.getAttribute(ATT_LOGIN_URL);
             defaultTargetUrl = elt.getAttribute(ATT_FORM_LOGIN_TARGET_URL);
             authenticationFailureUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL);
+            alwaysUseDefault = elt.getAttribute(ATT_ALWAYS_USE_DEFAULT_TARGET_URL);
             loginPage = elt.getAttribute(ATT_LOGIN_PAGE);
             if (!StringUtils.hasText(loginPage)) {
             	loginPage = null;
@@ -65,7 +68,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
 
         ConfigUtils.registerProviderManagerIfNecessary(parserContext);
         
-        filterBean = createFilterBean(loginUrl, defaultTargetUrl, loginPage, authenticationFailureUrl);
+        filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault, loginPage, authenticationFailureUrl);
 
         filterBean.setSource(source);
         filterBean.getPropertyValues().addPropertyValue("authenticationManager",
@@ -82,13 +85,19 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
         return null;
     }
 
-    private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String loginPage, String authenticationFailureUrl) {
+    private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String alwaysUseDefault, 
+    		String loginPage, String authenticationFailureUrl) {
+    	
         BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(filterClassName);
 
         if (!StringUtils.hasText(loginUrl)) {
         	loginUrl = defaultLoginProcessingUrl;
         }
 
+        if ("true".equals(alwaysUseDefault)) {
+        	filterBuilder.addPropertyValue("alwaysUseDefaultTargetUrl", Boolean.TRUE);
+        }
+        
         filterBuilder.addPropertyValue("filterProcessesUrl", loginUrl);
 
 

+ 3 - 0
core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc

@@ -262,6 +262,9 @@ form-login.attlist &=
 form-login.attlist &=
     ## The URL that will be redirected to after successful authentication, if the user's previous action could not be resumed. This generally happens if the user visits a login page without having first requested a secured operation that triggers authentication. If unspecified, defaults to the root of the application.
     attribute default-target-url {xsd:string}?
+form-login.attlist &=
+    ## Whether the user should always be redirected to the default-target-url after login. 
+    attribute always-use-default-target {boolean}?    
 form-login.attlist &=
     ## The URL for the login page. If no login URL is specified, Spring Security will automatically create a login URL at /spring_security_login and a corresponding filter to render that login URL when requested.
     attribute login-page {xsd:string}?

+ 46 - 41
core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd

@@ -296,7 +296,46 @@
     </xs:annotation>
     <xs:complexType>
       <xs:sequence>
-        <xs:element minOccurs="0" ref="security:password-compare"/>
+        <xs:element minOccurs="0" name="password-compare">
+          <xs:annotation>
+            <xs:documentation>Specifies that an LDAP provider should use an LDAP compare operation
+              of the user's password to authenticate the user</xs:documentation>
+          </xs:annotation>
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element minOccurs="0" name="password-encoder">
+                <xs:annotation>
+                  <xs:documentation>element which defines a password encoding strategy. Used by an
+                    authentication provider to convert submitted passwords to hashed versions, for
+                    example.</xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                  <xs:sequence>
+                    <xs:element minOccurs="0" name="salt-source">
+                      <xs:complexType>
+                        <xs:attribute name="user-property" type="xs:string">
+                          <xs:annotation>
+                            <xs:documentation>A property of the UserDetails object which will be
+                              used as salt by a password encoder. Typically something like
+                              "username" might be used. </xs:documentation>
+                          </xs:annotation>
+                        </xs:attribute>
+                        <xs:attribute name="system-wide" type="xs:string">
+                          <xs:annotation>
+                            <xs:documentation>A single value that will be used as the salt for a
+                              password encoder. </xs:documentation>
+                          </xs:annotation>
+                        </xs:attribute>
+                      </xs:complexType>
+                    </xs:element>
+                  </xs:sequence>
+                  <xs:attributeGroup ref="security:password-encoder.attlist"/>
+                </xs:complexType>
+              </xs:element>
+            </xs:sequence>
+            <xs:attributeGroup ref="security:password-compare.attlist"/>
+          </xs:complexType>
+        </xs:element>
       </xs:sequence>
       <xs:attributeGroup ref="security:ldap-ap.attlist"/>
     </xs:complexType>
@@ -337,46 +376,6 @@
       </xs:annotation>
     </xs:attribute>
   </xs:attributeGroup>
-  <xs:element name="password-compare">
-    <xs:annotation>
-      <xs:documentation>Specifies that an LDAP provider should use an LDAP compare operation of the
-        user's password to authenticate the user</xs:documentation>
-    </xs:annotation>
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element minOccurs="0" name="password-encoder">
-          <xs:annotation>
-            <xs:documentation>element which defines a password encoding strategy. Used by an
-              authentication provider to convert submitted passwords to hashed versions, for
-              example.</xs:documentation>
-          </xs:annotation>
-          <xs:complexType>
-            <xs:sequence>
-              <xs:element minOccurs="0" name="salt-source">
-                <xs:complexType>
-                  <xs:attribute name="user-property" type="xs:string">
-                    <xs:annotation>
-                      <xs:documentation>A property of the UserDetails object which will be used as
-                        salt by a password encoder. Typically something like "username" might be
-                        used. </xs:documentation>
-                    </xs:annotation>
-                  </xs:attribute>
-                  <xs:attribute name="system-wide" type="xs:string">
-                    <xs:annotation>
-                      <xs:documentation>A single value that will be used as the salt for a password
-                        encoder. </xs:documentation>
-                    </xs:annotation>
-                  </xs:attribute>
-                </xs:complexType>
-              </xs:element>
-            </xs:sequence>
-            <xs:attributeGroup ref="security:password-encoder.attlist"/>
-          </xs:complexType>
-        </xs:element>
-      </xs:sequence>
-      <xs:attributeGroup ref="security:password-compare.attlist"/>
-    </xs:complexType>
-  </xs:element>
   <xs:attributeGroup name="password-compare.attlist">
     <xs:attribute name="password-attribute" type="xs:string">
       <xs:annotation>
@@ -805,6 +804,12 @@
         application.</xs:documentation>
       </xs:annotation>
     </xs:attribute>
+    <xs:attribute name="always-use-default-target" type="security:boolean">
+      <xs:annotation>
+        <xs:documentation>Whether the user should always be redirected to the default-target-url
+          after login. </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
     <xs:attribute name="login-page" type="xs:string">
       <xs:annotation>
         <xs:documentation>The URL for the login page. If no login URL is specified, Spring Security

+ 15 - 7
core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java

@@ -131,12 +131,24 @@ public class HttpSecurityBeanDefinitionParserTests {
     @Test
     public void formLoginWithNoLoginPageAddsDefaultLoginPageFilter() throws Exception {
         setContext(
-                "    <http auto-config='true' path-type='ant' lowercase-comparisons='false'>" +
-                "        <form-login />" +
-                "    </http>" + AUTH_PROVIDER_XML);
+                "<http auto-config='true' path-type='ant' lowercase-comparisons='false'>" +
+                "   <form-login />" +
+                "</http>" + AUTH_PROVIDER_XML);
         // These will be matched by the default pattern "/**"
         checkAutoConfigFilters(getFilters("/anything"));
     }
+
+    @Test
+    public void formLoginAlwaysUseDefaultSetsCorrectProperty() throws Exception {
+        setContext(
+                "<http>" +
+                "   <form-login default-target-url='/default' always-use-default-target='true' />" +
+                "</http>" + AUTH_PROVIDER_XML);
+        // These will be matched by the default pattern "/**"
+        AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) getFilters("/anything").get(2);
+        assertEquals("/default", filter.getDefaultTargetUrl());
+        assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "alwaysUseDefaultTargetUrl"));
+    }
     
     @Test
     public void lowerCaseComparisonIsRespectedBySecurityFilterInvocationDefinitionSource() throws Exception {
@@ -385,10 +397,6 @@ public class HttpSecurityBeanDefinitionParserTests {
         getFilters.setAccessible(true);
         return (List) ReflectionUtils.invokeMethod(getFilters, fcp, new Object[] {url});
     }
-    
-    private FilterChainProxy getFilterChainProxy() {
-        return (FilterChainProxy) appContext.getBean(BeanIds.FILTER_CHAIN_PROXY);
-    }
 
     private FilterInvocation createFilterinvocation(String path, String method) {
         MockHttpServletRequest request = new MockHttpServletRequest();