mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 17:22:13 +00:00
SEC-1657: Added support for 'name' attribute in <http> element to expose filter chain as a list bean.
This commit is contained in:
parent
f20649f035
commit
2eefbf3a23
@ -2,6 +2,7 @@ package org.springframework.security.config.http;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanReference;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
@ -26,8 +27,9 @@ public class HttpFirewallBeanDefinitionParser implements BeanDefinitionParser {
|
||||
pc.getReaderContext().error("ref attribute is required", pc.extractSource(element));
|
||||
}
|
||||
|
||||
// Ensure the FCP is registered.
|
||||
HttpSecurityBeanDefinitionParser.registerFilterChainProxy(pc,
|
||||
new ManagedMap<BeanDefinition, List<BeanMetadataElement>>(),
|
||||
new ManagedMap<BeanDefinition, BeanReference>(),
|
||||
pc.extractSource(element));
|
||||
BeanDefinition filterChainProxy = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAIN_PROXY);
|
||||
filterChainProxy.getPropertyValues().addPropertyValue("firewall", new RuntimeBeanReference(ref));
|
||||
|
@ -10,6 +10,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanReference;
|
||||
import org.springframework.beans.factory.config.ListFactoryBean;
|
||||
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
@ -72,7 +73,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
pc.pushContainingComponent(compositeDef);
|
||||
|
||||
MatcherType matcherType = MatcherType.fromElement(element);
|
||||
ManagedMap<BeanDefinition, List<BeanMetadataElement>> filterChainMap = new ManagedMap<BeanDefinition, List<BeanMetadataElement>>();
|
||||
ManagedMap<BeanDefinition, BeanReference> filterChainMap = new ManagedMap<BeanDefinition, BeanReference>();
|
||||
|
||||
String filterChainPattern = element.getAttribute(ATT_PATH_PATTERN);
|
||||
|
||||
@ -92,7 +93,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<BeanMetadataElement> createFilterChain(Element element, ParserContext pc, MatcherType matcherType) {
|
||||
BeanReference createFilterChain(Element element, ParserContext pc, MatcherType matcherType) {
|
||||
boolean secured = !OPT_SECURITY_NONE.equals(element.getAttribute(ATT_SECURED));
|
||||
|
||||
if (!secured) {
|
||||
@ -108,7 +109,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
return createFilterListBean(element, pc, Collections.emptyList());
|
||||
}
|
||||
|
||||
final String portMapperName = createPortMapper(element, pc);
|
||||
@ -140,9 +141,24 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
filterChain.add(od.bean);
|
||||
}
|
||||
|
||||
return filterChain;
|
||||
return createFilterListBean(element, pc, filterChain);
|
||||
}
|
||||
|
||||
private BeanReference createFilterListBean(Element element, ParserContext pc, List<?> filterChain) {
|
||||
BeanDefinition listFactoryBean = new RootBeanDefinition(ListFactoryBean.class);
|
||||
|
||||
String id = element.getAttribute("name");
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = element.getAttribute("id");
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = pc.getReaderContext().generateBeanName(listFactoryBean);
|
||||
}
|
||||
}
|
||||
listFactoryBean.getPropertyValues().add("sourceList", filterChain);
|
||||
pc.registerBeanComponent(new BeanComponentDefinition(listFactoryBean, id));
|
||||
|
||||
return new RuntimeBeanReference(id);
|
||||
}
|
||||
|
||||
private String createPortMapper(Element elt, ParserContext pc) {
|
||||
// Register the portMapper. A default will always be created, even if no element exists.
|
||||
@ -247,7 +263,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static void registerFilterChainProxy(ParserContext pc, Map<BeanDefinition, List<BeanMetadataElement>> filterChainMap, Object source) {
|
||||
static void registerFilterChainProxy(ParserContext pc, Map<BeanDefinition, BeanReference> filterChainMap, Object source) {
|
||||
if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
|
||||
// Already registered. Obtain the filter chain map and add the new entries to it
|
||||
|
||||
|
@ -25,6 +25,9 @@ url =
|
||||
id =
|
||||
## A bean identifier, used for referring to the bean elsewhere in the context.
|
||||
attribute id {xsd:ID}
|
||||
name =
|
||||
## A bean identifier, used for referring to the bean elsewhere in the context.
|
||||
attribute name {xsd:ID}
|
||||
ref =
|
||||
## Defines a reference to a Spring bean Id.
|
||||
attribute ref {xsd:token}
|
||||
@ -311,6 +314,10 @@ http.attlist &=
|
||||
http.attlist &=
|
||||
## Prevents the jsessionid parameter from being added to rendered URLs.
|
||||
attribute disable-url-rewriting {xsd:boolean}?
|
||||
http.attlist &=
|
||||
## Exposes the list of filters defined by this configuration under this bean name in the application context. May be used by
|
||||
name?
|
||||
|
||||
|
||||
access-denied-handler =
|
||||
## Defines the access-denied strategy that should be used. An access denied page can be defined or a reference to an AccessDeniedHandler instance.
|
||||
|
@ -70,6 +70,13 @@
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:attributeGroup name="name">
|
||||
<xs:attribute name="name" use="required" type="xs:ID">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A bean identifier, used for referring to the bean elsewhere in the context.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:attributeGroup name="ref">
|
||||
<xs:attribute name="ref" use="required" type="xs:token">
|
||||
<xs:annotation>
|
||||
@ -781,6 +788,11 @@
|
||||
<xs:documentation>Prevents the jsessionid parameter from being added to rendered URLs.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="name" type="xs:ID">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A bean identifier, used for referring to the bean elsewhere in the context.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="access-denied-handler.attlist">
|
||||
|
@ -3,6 +3,7 @@ package org.springframework.security.config.http
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException
|
||||
import org.springframework.security.config.BeanIds
|
||||
import org.springframework.security.web.FilterChainProxy
|
||||
import org.junit.Assert
|
||||
|
||||
/**
|
||||
* Tests scenarios with multiple <http> elements.
|
||||
@ -40,4 +41,21 @@ class MultiHttpBlockConfigTests extends AbstractHttpConfigTests {
|
||||
then:
|
||||
thrown(BeanDefinitionParsingException)
|
||||
}
|
||||
|
||||
def namedFilterChainIsExposedAsABean () {
|
||||
xml.http(name: 'basic', pattern: '/basic/**', 'create-session': 'stateless') {
|
||||
'http-basic'()
|
||||
}
|
||||
xml.http(pattern: '/form/**') {
|
||||
'form-login'()
|
||||
}
|
||||
createAppContext()
|
||||
def fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
||||
List filterChains = fcp.getFilterChainMap().values() as List;
|
||||
List basicChain = filterChains[0];
|
||||
|
||||
expect:
|
||||
Assert.assertSame (basicChain, appContext.getBean('basic'))
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user