SEC-1725: Add option to filter-chain to use an explicit request-matcher-ref instead of a "path" attribute.

This commit is contained in:
Luke Taylor 2011-04-25 23:20:15 +01:00
parent f883c6e579
commit b5924db74d
4 changed files with 27 additions and 17 deletions

View File

@ -5,7 +5,10 @@ import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@ -14,20 +17,24 @@ import java.util.*;
/**
* @author Luke Taylor
*/
public class FilterChainBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
public class FilterChainBeanDefinitionParser implements BeanDefinitionParser {
private static final String ATT_REQUEST_MATCHER_REF = "request-matcher-ref";
@Override
protected Class getBeanClass(Element element) {
return SecurityFilterChain.class;
}
@Override
protected void doParse(Element elt, BeanDefinitionBuilder builder) {
public BeanDefinition parse(Element elt, ParserContext pc) {
MatcherType matcherType = MatcherType.fromElement(elt);
String path = elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_PATH_PATTERN);
String requestMatcher = elt.getAttribute(ATT_REQUEST_MATCHER_REF);
String filters = elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS);
builder.addConstructorArgValue(matcherType.createMatcher(path, null));
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(SecurityFilterChain.class);
if (StringUtils.hasText(path)) {
Assert.isTrue(!StringUtils.hasText(requestMatcher), "");
builder.addConstructorArgValue(matcherType.createMatcher(path, null));
} else {
Assert.isTrue(StringUtils.hasText(requestMatcher), "");
builder.addConstructorArgReference(requestMatcher);
}
if (filters.equals(HttpSecurityBeanDefinitionParser.OPT_FILTERS_NONE)) {
builder.addConstructorArgValue(Collections.EMPTY_LIST);
@ -41,5 +48,7 @@ public class FilterChainBeanDefinitionParser extends AbstractSingleBeanDefinitio
builder.addConstructorArgValue(filterChain);
}
return builder.getBeanDefinition();
}
}

View File

@ -446,7 +446,7 @@ filter-chain =
## Used within to define a specific URL pattern and the list of filters which apply to the URLs matching that pattern. When multiple filter-chain elements are assembled in a list in order to configure a FilterChainProxy, the most specific patterns must be placed at the top of the list, with most general ones at the bottom.
element filter-chain {filter-chain.attlist, empty}
filter-chain.attlist &=
attribute pattern {xsd:token}
(attribute pattern {xsd:token} | attribute request-matcher-ref {xsd:token})
filter-chain.attlist &=
attribute filters {xsd:token}

View File

@ -1006,7 +1006,8 @@
<xs:attributeGroup ref="security:filter-chain.attlist"/>
</xs:complexType></xs:element>
<xs:attributeGroup name="filter-chain.attlist">
<xs:attribute name="pattern" use="required" type="xs:token"/>
<xs:attribute name="pattern" type="xs:token"/>
<xs:attribute name="request-matcher-ref" type="xs:token"/>
<xs:attribute name="filters" use="required" type="xs:token"/>
</xs:attributeGroup>
<xs:element name="filter-security-metadata-source"><xs:annotation>

View File

@ -47,10 +47,14 @@
<bean id="mockNotAFilter" class="org.springframework.security.web.util.AnyRequestMatcher"/>
<bean id="fooMatcher" class="org.springframework.security.web.util.AntPathRequestMatcher">
<constructor-arg value="/foo/**"/>
</bean>
<bean id="filterChain" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<util:list>
<sec:filter-chain pattern="/foo/**" filters="mockFilter"/>
<sec:filter-chain request-matcher-ref="fooMatcher" filters="mockFilter"/>
<sec:filter-chain pattern="/some/other/path/**" filters="mockFilter"/>
<sec:filter-chain pattern="/do/not/filter" filters="none"/>
</util:list>
@ -121,11 +125,7 @@
<constructor-arg>
<list>
<bean class="org.springframework.security.web.SecurityFilterChain">
<constructor-arg>
<bean class="org.springframework.security.web.util.AntPathRequestMatcher">
<constructor-arg value="/foo/**"/>
</bean>
</constructor-arg>
<constructor-arg ref="fooMatcher"/>
<constructor-arg>
<list>
<ref local="mockFilter"/>