diff --git a/config/src/main/java/org/springframework/security/config/http/WebConfigUtils.java b/config/src/main/java/org/springframework/security/config/http/WebConfigUtils.java index 746c5e4ae4..d87ed7d570 100644 --- a/config/src/main/java/org/springframework/security/config/http/WebConfigUtils.java +++ b/config/src/main/java/org/springframework/security/config/http/WebConfigUtils.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.security.config.http; import org.springframework.beans.factory.xml.ParserContext; @@ -26,10 +41,10 @@ abstract class WebConfigUtils { /** * Checks the value of an XML attribute which represents a redirect URL. - * If not empty or starting with "$" (potential placeholder), "/" or "http" it will raise an error. + * If not empty or starting with "$" (potential placeholder), or starting with "#" (potential SpEL), "/" or "http" it will raise an error. */ static void validateHttpRedirect(String url, ParserContext pc, Object source) { - if (!StringUtils.hasText(url) || UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) { + if (!StringUtils.hasText(url) || UrlUtils.isValidRedirectUrl(url) || url.startsWith("$") || url.startsWith("#")) { return; } pc.getReaderContext().warning(url + " is not a valid redirect URL (must start with '/' or http(s))", source); diff --git a/config/src/test/groovy/org/springframework/security/config/http/FormLoginConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/FormLoginConfigTests.groovy index c040b211d1..66b1bd3b78 100644 --- a/config/src/test/groovy/org/springframework/security/config/http/FormLoginConfigTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/http/FormLoginConfigTests.groovy @@ -2,6 +2,7 @@ package org.springframework.security.config.http import org.springframework.beans.factory.BeanCreationException import org.springframework.security.util.FieldUtils +import org.springframework.security.web.access.ExceptionTranslationFilter import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter @@ -32,6 +33,26 @@ class FormLoginConfigTests extends AbstractHttpConfigTests { FieldUtils.getFieldValue(filter, 'successHandler.alwaysUseDefaultTargetUrl'); } + def 'form-login attributes support SpEL'() { + setup: + def spelUrl = '#{T(org.springframework.security.config.http.WebConfigUtilsTest).URL}' + def expectedUrl = WebConfigUtilsTest.URL + when: + xml.http { + 'form-login'('default-target-url': spelUrl , 'authentication-failure-url': spelUrl, 'login-page': spelUrl) + } + createAppContext() + def unPwdFilter = getFilter(UsernamePasswordAuthenticationFilter) + def exTransFilter = getFilter(ExceptionTranslationFilter) + + then: + unPwdFilter.successHandler.defaultTargetUrl == expectedUrl + unPwdFilter + FieldUtils.getFieldValue(unPwdFilter, 'successHandler.defaultTargetUrl') == expectedUrl + FieldUtils.getFieldValue(unPwdFilter, 'failureHandler.defaultFailureUrl') == expectedUrl + FieldUtils.getFieldValue(exTransFilter, 'authenticationEntryPoint.loginFormUrl') == expectedUrl + } + def invalidLoginPageIsDetected() { when: xml.http { diff --git a/config/src/test/java/org/springframework/security/config/http/WebConfigUtilsTest.java b/config/src/test/java/org/springframework/security/config/http/WebConfigUtilsTest.java new file mode 100644 index 0000000000..c4b372ee43 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/http/WebConfigUtilsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.config.http; + +import static org.mockito.Mockito.verifyZeroInteractions; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.beans.factory.xml.ParserContext; + + +@RunWith(PowerMockRunner.class) +@PrepareOnlyThisForTest(ParserContext.class) +public class WebConfigUtilsTest { + public final static String URL = "/url"; + + @Mock + private ParserContext parserContext; + + // SEC-1980 + @Test + public void validateHttpRedirectSpELNoParserWarning() { + WebConfigUtils.validateHttpRedirect("#{T(org.springframework.security.config.http.WebConfigUtilsTest).URL}", parserContext, "fakeSource"); + verifyZeroInteractions(parserContext); + } +} \ No newline at end of file