mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-24 13:02:13 +00:00
OPEN - issue SEC-953: Query string isn't ignored while url - filterchain pattern matching
http://jira.springframework.org/browse/SEC-953. Added stripQueryStringFromUrls parameter to FilterChainProxy which works the same as the one on DefaultFilterInvocationDefinitionSource. This defaults to true when used with ant path matching.
This commit is contained in:
parent
b6dec19e90
commit
39a656eb78
@ -208,6 +208,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||||||
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
|
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
|
||||||
filterChainProxy.setSource(source);
|
filterChainProxy.setSource(source);
|
||||||
filterChainProxy.getPropertyValues().addPropertyValue("matcher", matcher);
|
filterChainProxy.getPropertyValues().addPropertyValue("matcher", matcher);
|
||||||
|
filterChainProxy.getPropertyValues().addPropertyValue("stripQueryStringFromUrls", matcher instanceof AntUrlPathMatcher);
|
||||||
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
|
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
|
||||||
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy);
|
pc.getRegistry().registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy);
|
||||||
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||||
|
@ -107,6 +107,7 @@ public class FilterChainProxy implements Filter, InitializingBean, ApplicationCo
|
|||||||
/** Compiled pattern version of the filter chain map */
|
/** Compiled pattern version of the filter chain map */
|
||||||
private Map filterChainMap;
|
private Map filterChainMap;
|
||||||
private UrlMatcher matcher = new AntUrlPathMatcher();
|
private UrlMatcher matcher = new AntUrlPathMatcher();
|
||||||
|
private boolean stripQueryStringFromUrls = true;
|
||||||
private DefaultFilterInvocationDefinitionSource fids;
|
private DefaultFilterInvocationDefinitionSource fids;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
@ -181,6 +182,16 @@ public class FilterChainProxy implements Filter, InitializingBean, ApplicationCo
|
|||||||
* @return an ordered array of Filters defining the filter chain
|
* @return an ordered array of Filters defining the filter chain
|
||||||
*/
|
*/
|
||||||
public List getFilters(String url) {
|
public List getFilters(String url) {
|
||||||
|
if (stripQueryStringFromUrls) {
|
||||||
|
// String query string - see SEC-953
|
||||||
|
int firstQuestionMarkIndex = url.indexOf("?");
|
||||||
|
|
||||||
|
if (firstQuestionMarkIndex != -1) {
|
||||||
|
url = url.substring(0, firstQuestionMarkIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Iterator filterChains = filterChainMap.entrySet().iterator();
|
Iterator filterChains = filterChainMap.entrySet().iterator();
|
||||||
|
|
||||||
while (filterChains.hasNext()) {
|
while (filterChains.hasNext()) {
|
||||||
@ -319,6 +330,14 @@ public class FilterChainProxy implements Filter, InitializingBean, ApplicationCo
|
|||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to 'true', the query string will be stripped from the request URL before
|
||||||
|
* attempting to find a matching filter chain. This is the default value.
|
||||||
|
*/
|
||||||
|
public void setStripQueryStringFromUrls(boolean stripQueryStringFromUrls) {
|
||||||
|
this.stripQueryStringFromUrls = stripQueryStringFromUrls;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("FilterChainProxy[");
|
sb.append("FilterChainProxy[");
|
||||||
|
@ -79,6 +79,8 @@ public class HttpSecurityBeanDefinitionParserTests {
|
|||||||
List filterList = getFilters("/anyurl");
|
List filterList = getFilters("/anyurl");
|
||||||
|
|
||||||
checkAutoConfigFilters(filterList);
|
checkAutoConfigFilters(filterList);
|
||||||
|
|
||||||
|
assertEquals(true, FieldUtils.getFieldValue(appContext.getBean("_filterChainProxy"), "stripQueryStringFromUrls"));
|
||||||
assertEquals(true, FieldUtils.getFieldValue(filterList.get(10), "objectDefinitionSource.stripQueryStringFromUrls"));
|
assertEquals(true, FieldUtils.getFieldValue(filterList.get(10), "objectDefinitionSource.stripQueryStringFromUrls"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +138,7 @@ public class HttpSecurityBeanDefinitionParserTests {
|
|||||||
// This will be matched by the default pattern ".*"
|
// This will be matched by the default pattern ".*"
|
||||||
List allFilters = getFilters("/ImCaughtByTheUniversalMatchPattern");
|
List allFilters = getFilters("/ImCaughtByTheUniversalMatchPattern");
|
||||||
checkAutoConfigFilters(allFilters);
|
checkAutoConfigFilters(allFilters);
|
||||||
|
assertEquals(false, FieldUtils.getFieldValue(appContext.getBean("_filterChainProxy"), "stripQueryStringFromUrls"));
|
||||||
assertEquals(false, FieldUtils.getFieldValue(allFilters.get(10), "objectDefinitionSource.stripQueryStringFromUrls"));
|
assertEquals(false, FieldUtils.getFieldValue(allFilters.get(10), "objectDefinitionSource.stripQueryStringFromUrls"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +152,6 @@ public class HttpSecurityBeanDefinitionParserTests {
|
|||||||
// These will be matched by the default pattern "/**"
|
// These will be matched by the default pattern "/**"
|
||||||
checkAutoConfigFilters(getFilters("/secure"));
|
checkAutoConfigFilters(getFilters("/secure"));
|
||||||
checkAutoConfigFilters(getFilters("/ImCaughtByTheUniversalMatchPattern"));
|
checkAutoConfigFilters(getFilters("/ImCaughtByTheUniversalMatchPattern"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -62,20 +62,16 @@ public class FilterChainProxyTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected=IllegalArgumentException.class)
|
||||||
public void testDetectsFilterInvocationDefinitionSourceThatDoesNotReturnAllConfigAttributes() throws Exception {
|
public void testDetectsFilterInvocationDefinitionSourceThatDoesNotReturnAllConfigAttributes() throws Exception {
|
||||||
FilterChainProxy filterChainProxy = new FilterChainProxy();
|
FilterChainProxy filterChainProxy = new FilterChainProxy();
|
||||||
filterChainProxy.setApplicationContext(new StaticApplicationContext());
|
filterChainProxy.setApplicationContext(new StaticApplicationContext());
|
||||||
|
|
||||||
try {
|
|
||||||
filterChainProxy.setFilterInvocationDefinitionSource(new MockFilterInvocationDefinitionSource(false, false));
|
filterChainProxy.setFilterInvocationDefinitionSource(new MockFilterInvocationDefinitionSource(false, false));
|
||||||
filterChainProxy.afterPropertiesSet();
|
filterChainProxy.afterPropertiesSet();
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected=IllegalArgumentException.class)
|
||||||
public void testDetectsIfConfigAttributeDoesNotReturnValueForGetAttributeMethod() throws Exception {
|
public void testDetectsIfConfigAttributeDoesNotReturnValueForGetAttributeMethod() throws Exception {
|
||||||
FilterChainProxy filterChainProxy = new FilterChainProxy();
|
FilterChainProxy filterChainProxy = new FilterChainProxy();
|
||||||
filterChainProxy.setApplicationContext(new StaticApplicationContext());
|
filterChainProxy.setApplicationContext(new StaticApplicationContext());
|
||||||
@ -89,12 +85,8 @@ public class FilterChainProxyTests {
|
|||||||
|
|
||||||
filterChainProxy.setFilterInvocationDefinitionSource(fids);
|
filterChainProxy.setFilterInvocationDefinitionSource(fids);
|
||||||
|
|
||||||
try {
|
|
||||||
filterChainProxy.afterPropertiesSet();
|
filterChainProxy.afterPropertiesSet();
|
||||||
filterChainProxy.init(new MockFilterConfig());
|
filterChainProxy.init(new MockFilterConfig());
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
@ -164,6 +156,24 @@ public class FilterChainProxyTests {
|
|||||||
doNormalOperation(filterChainProxy);
|
doNormalOperation(filterChainProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathWithNoMatchHasNoFilters() throws Exception {
|
||||||
|
FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("newFilterChainProxyNoDefaultPath", FilterChainProxy.class);
|
||||||
|
assertEquals(null, filterChainProxy.getFilters("/nomatch"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void urlStrippingPropertyIsRespected() throws Exception {
|
||||||
|
FilterChainProxy filterChainProxy = (FilterChainProxy) appCtx.getBean("newFilterChainProxyNoDefaultPath", FilterChainProxy.class);
|
||||||
|
|
||||||
|
// Should only match if we are stripping the query string
|
||||||
|
String url = "/blah.bar?x=something";
|
||||||
|
assertNotNull(filterChainProxy.getFilters(url));
|
||||||
|
assertEquals(2, filterChainProxy.getFilters(url).size());
|
||||||
|
filterChainProxy.setStripQueryStringFromUrls(false);
|
||||||
|
assertNull(filterChainProxy.getFilters(url));
|
||||||
|
}
|
||||||
|
|
||||||
private void checkPathAndFilterOrder(FilterChainProxy filterChainProxy) throws Exception {
|
private void checkPathAndFilterOrder(FilterChainProxy filterChainProxy) throws Exception {
|
||||||
List filters = filterChainProxy.getFilters("/foo/blah");
|
List filters = filterChainProxy.getFilters("/foo/blah");
|
||||||
assertEquals(1, filters.size());
|
assertEquals(1, filters.size());
|
||||||
|
@ -73,6 +73,13 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
|
|||||||
</sec:filter-chain-map>
|
</sec:filter-chain-map>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="newFilterChainProxyNoDefaultPath" class="org.springframework.security.util.FilterChainProxy">
|
||||||
|
<sec:filter-chain-map path-type="ant">
|
||||||
|
<sec:filter-chain pattern="/foo/**" filters="mockFilter"/>
|
||||||
|
<sec:filter-chain pattern="/*.bar" filters="mockFilter,mockFilter2"/>
|
||||||
|
</sec:filter-chain-map>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="newFilterChainProxyWrongPathOrder" class="org.springframework.security.util.FilterChainProxy">
|
<bean id="newFilterChainProxyWrongPathOrder" class="org.springframework.security.util.FilterChainProxy">
|
||||||
<sec:filter-chain-map path-type="ant">
|
<sec:filter-chain-map path-type="ant">
|
||||||
<sec:filter-chain pattern="/foo/**" filters="mockFilter"/>
|
<sec:filter-chain pattern="/foo/**" filters="mockFilter"/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user