From 7145198e5a72f534b88c033662aafcbae4795d01 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Fri, 11 Apr 2008 12:03:55 +0000 Subject: [PATCH] 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. --- .../config/FormLoginBeanDefinitionParser.java | 13 ++- .../security/config/spring-security-2.0.rnc | 3 + .../security/config/spring-security-2.0.xsd | 87 ++++++++++--------- ...HttpSecurityBeanDefinitionParserTests.java | 22 +++-- 4 files changed, 75 insertions(+), 50 deletions(-) diff --git a/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java index 2eedaeec65..8f1b35d71a 100644 --- a/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java +++ b/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); diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc index 1bbfb1fa46..4ab27a4344 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc +++ b/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}? diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd index b5cce75f31..2576f2dfec 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd @@ -296,7 +296,46 @@ - + + + Specifies that an LDAP provider should use an LDAP compare operation + of the user's password to authenticate the user + + + + + + element which defines a password encoding strategy. Used by an + authentication provider to convert submitted passwords to hashed versions, for + example. + + + + + + + + A property of the UserDetails object which will be + used as salt by a password encoder. Typically something like + "username" might be used. + + + + + A single value that will be used as the salt for a + password encoder. + + + + + + + + + + + + @@ -337,46 +376,6 @@ - - - Specifies that an LDAP provider should use an LDAP compare operation of the - user's password to authenticate the user - - - - - - element which defines a password encoding strategy. Used by an - authentication provider to convert submitted passwords to hashed versions, for - example. - - - - - - - - A property of the UserDetails object which will be used as - salt by a password encoder. Typically something like "username" might be - used. - - - - - A single value that will be used as the salt for a password - encoder. - - - - - - - - - - - - @@ -805,6 +804,12 @@ application. + + + Whether the user should always be redirected to the default-target-url + after login. + + The URL for the login page. If no login URL is specified, Spring Security diff --git a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java index bf9a80ed0b..9b50b6ca7a 100644 --- a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java +++ b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java @@ -131,12 +131,24 @@ public class HttpSecurityBeanDefinitionParserTests { @Test public void formLoginWithNoLoginPageAddsDefaultLoginPageFilter() throws Exception { setContext( - " " + - " " + - " " + AUTH_PROVIDER_XML); + "" + + " " + + "" + AUTH_PROVIDER_XML); // These will be matched by the default pattern "/**" checkAutoConfigFilters(getFilters("/anything")); } + + @Test + public void formLoginAlwaysUseDefaultSetsCorrectProperty() throws Exception { + setContext( + "" + + " " + + "" + 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();