diff --git a/core/src/main/java/org/springframework/security/util/FilterChainProxy.java b/core/src/main/java/org/springframework/security/util/FilterChainProxy.java index 3c449d9053..f285bd9c90 100644 --- a/core/src/main/java/org/springframework/security/util/FilterChainProxy.java +++ b/core/src/main/java/org/springframework/security/util/FilterChainProxy.java @@ -117,6 +117,7 @@ public class FilterChainProxy implements Filter, InitializingBean, ApplicationCo } Assert.notNull(uncompiledFilterChainMap, "filterChainMap must be set"); + } public void init(FilterConfig filterConfig) throws ServletException { @@ -247,9 +248,24 @@ public class FilterChainProxy implements Filter, InitializingBean, ApplicationCo */ public void setFilterChainMap(Map filterChainMap) { uncompiledFilterChainMap = new LinkedHashMap(filterChainMap); + checkPathOrder(); createCompiledMap(); } + private void checkPathOrder() { + // Check that the universal pattern is listed at the end, if at all + String[] paths = (String[]) uncompiledFilterChainMap.keySet().toArray(new String[0]); + String universalMatch = matcher.getUniversalMatchPattern(); + + for (int i=0; i < paths.length-1; i++) { + if (paths[i].equals(universalMatch)) { + throw new IllegalArgumentException("A universal match pattern " + universalMatch + " is defined " + + " before other patterns in the filter chain, causing them to be ignored. Please check the " + + "ordering in your namespace or FilterChainProxy bean configuration"); + } + } + } + private void createCompiledMap() { Iterator paths = uncompiledFilterChainMap.keySet().iterator(); filterChainMap = new LinkedHashMap(uncompiledFilterChainMap.size()); diff --git a/core/src/test/java/org/springframework/security/util/FilterChainProxyTests.java b/core/src/test/java/org/springframework/security/util/FilterChainProxyTests.java index 0efd25ce4b..16a0231c15 100644 --- a/core/src/test/java/org/springframework/security/util/FilterChainProxyTests.java +++ b/core/src/test/java/org/springframework/security/util/FilterChainProxyTests.java @@ -16,6 +16,11 @@ package org.springframework.security.util; +import org.junit.After; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -28,11 +33,6 @@ import org.springframework.security.intercept.web.MockFilterInvocationDefinition import org.springframework.security.intercept.web.PathBasedFilterInvocationDefinitionMap; import org.springframework.security.ui.webapp.AuthenticationProcessingFilter; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.*; - import java.util.List; /** @@ -126,6 +126,15 @@ public class FilterChainProxyTests { assertFalse(filter.isWasDestroyed()); } + @Test + public void misplacedUniversalPathShouldBeDetected() throws Exception { + try { + appCtx.getBean("newFilterChainProxyWrongPathOrder", FilterChainProxy.class); + fail("Expected BeanCreationException"); + } catch (BeanCreationException expected) { + } + } + @Test public void normalOperation() throws Exception { FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("filterChain", FilterChainProxy.class); diff --git a/core/src/test/resources/org/springframework/security/util/filtertest-valid.xml b/core/src/test/resources/org/springframework/security/util/filtertest-valid.xml index 0866bc180e..e2ca1ea8d3 100644 --- a/core/src/test/resources/org/springframework/security/util/filtertest-valid.xml +++ b/core/src/test/resources/org/springframework/security/util/filtertest-valid.xml @@ -18,7 +18,7 @@ * * $Id$ --> - + + + + + + +