SEC-1584: Added namespace support for injecting custom HttpFirewall instance into FilterChainProxy.
This commit is contained in:
parent
0961671772
commit
173537f4f2
|
@ -53,4 +53,5 @@ public abstract class Elements {
|
|||
public static final String FILTER_INVOCATION_DEFINITION_SOURCE = "filter-invocation-definition-source";
|
||||
public static final String LDAP_PASSWORD_COMPARE = "password-compare";
|
||||
public static final String DEBUG = "debug";
|
||||
public static final String HTTP_FIREWALL = "http-firewall";
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.springframework.security.config.authentication.JdbcUserServiceBeanDef
|
|||
import org.springframework.security.config.authentication.UserServiceBeanDefinitionParser;
|
||||
import org.springframework.security.config.http.FilterChainMapBeanDefinitionDecorator;
|
||||
import org.springframework.security.config.http.FilterInvocationSecurityMetadataSourceParser;
|
||||
import org.springframework.security.config.http.HttpFirewallBeanDefinitionParser;
|
||||
import org.springframework.security.config.http.HttpSecurityBeanDefinitionParser;
|
||||
import org.springframework.security.config.ldap.LdapProviderBeanDefinitionParser;
|
||||
import org.springframework.security.config.ldap.LdapServerBeanDefinitionParser;
|
||||
|
@ -116,11 +117,12 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
|||
parsers.put(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
|
||||
parsers.put(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
|
||||
parsers.put(Elements.METHOD_SECURITY_METADATA_SOURCE, new MethodSecurityMetadataSourceBeanDefinitionParser());
|
||||
parsers.put(Elements.DEBUG, new DebugBeanDefinitionParser());
|
||||
|
||||
// Only load the web-namespace parsers if the web classes are available
|
||||
if (ClassUtils.isPresent("org.springframework.security.web.FilterChainProxy", getClass().getClassLoader())) {
|
||||
parsers.put(Elements.DEBUG, new DebugBeanDefinitionParser());
|
||||
parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
|
||||
parsers.put(Elements.HTTP_FIREWALL, new HttpFirewallBeanDefinitionParser());
|
||||
parsers.put(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
parsers.put(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
|
||||
filterChainMapBDD = new FilterChainMapBeanDefinitionDecorator();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.springframework.security.config.http;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.config.BeanIds;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Injects the supplied {@code HttpFirewall} bean reference into the {@code FilterChainProxy}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class HttpFirewallBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext pc) {
|
||||
String ref = element.getAttribute("ref");
|
||||
|
||||
if (!StringUtils.hasText(ref)) {
|
||||
pc.getReaderContext().error("ref attribute is required", pc.extractSource(element));
|
||||
}
|
||||
|
||||
HttpSecurityBeanDefinitionParser.registerFilterChainProxy(pc,
|
||||
new ManagedMap<BeanDefinition, List<BeanMetadataElement>>(),
|
||||
pc.extractSource(element));
|
||||
BeanDefinition filterChainProxy = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAIN_PROXY);
|
||||
filterChainProxy.getPropertyValues().addPropertyValue("firewall", new RuntimeBeanReference(ref));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -247,10 +247,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void registerFilterChainProxy(ParserContext pc, Map<BeanDefinition, List<BeanMetadataElement>> filterChainMap, Object source) {
|
||||
static void registerFilterChainProxy(ParserContext pc, Map<BeanDefinition, List<BeanMetadataElement>> 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
|
||||
// pc.getReaderContext().error("Duplicate <http> element detected", source);
|
||||
|
||||
BeanDefinition fcp = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAIN_PROXY);
|
||||
Map existingFilterChainMap = (Map) fcp.getPropertyValues().getPropertyValue("filterChainMap").getValue();
|
||||
|
|
|
@ -257,6 +257,9 @@ protect-pointcut.attlist &=
|
|||
## Access configuration attributes list that applies to all methods matching the pointcut, e.g. "ROLE_A,ROLE_B"
|
||||
attribute access {xsd:token}
|
||||
|
||||
http-firewall =
|
||||
## Allows a custom instance of HttpFirewall to be injected into the FilterChainProxy created by the namespace.
|
||||
element http-firewall {ref}
|
||||
|
||||
http =
|
||||
## Container element for HTTP security configuration. Multiple elements can now be defined, each with a specific pattern to which the enclosed security configuration applies. A pattern can also be configured to bypass Spring Security's filters completely by setting the "secured" attribute to "false".
|
||||
|
|
|
@ -589,6 +589,11 @@
|
|||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="http-firewall"><xs:annotation>
|
||||
<xs:documentation>Allows a custom instance of HttpFirewall to be injected into the FilterChainProxy created by the namespace.</xs:documentation>
|
||||
</xs:annotation><xs:complexType>
|
||||
<xs:attributeGroup ref="security:ref"/>
|
||||
</xs:complexType></xs:element>
|
||||
<xs:element name="http"><xs:annotation>
|
||||
<xs:documentation>Container element for HTTP security configuration. Multiple elements can now be defined, each with a specific pattern to which the enclosed security configuration applies. A pattern can also be configured to bypass Spring Security's filters completely by setting the "secured" attribute to "false".</xs:documentation>
|
||||
</xs:annotation><xs:complexType>
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.springframework.security.web.savedrequest.RequestCacheAwareFilter
|
|||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
|
||||
import org.springframework.security.web.session.SessionManagementFilter
|
||||
import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler
|
||||
import org.springframework.security.web.firewall.DefaultHttpFirewall
|
||||
|
||||
class MiscHttpConfigTests extends AbstractHttpConfigTests {
|
||||
def 'Minimal configuration parses'() {
|
||||
|
@ -582,13 +583,24 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests {
|
|||
getFilter(BasicAuthenticationFilter).authenticationDetailsSource == adsr
|
||||
getFilter(X509AuthenticationFilter).authenticationDetailsSource == adsr
|
||||
}
|
||||
|
||||
|
||||
def includeJaasApiIntegrationFilter() {
|
||||
xml.http(['auto-config':'true','jaas-api-provision':'true'])
|
||||
createAppContext()
|
||||
expect:
|
||||
getFilter(JaasApiIntegrationFilter.class) != null
|
||||
|
||||
}
|
||||
|
||||
def httpFirewallInjectionIsSupported() {
|
||||
xml.'http-firewall'(ref: 'fw')
|
||||
xml.http() {
|
||||
'form-login'()
|
||||
}
|
||||
bean('fw', DefaultHttpFirewall)
|
||||
createAppContext()
|
||||
FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
||||
expect:
|
||||
fcp.firewall == appContext.getBean('fw')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -524,12 +524,19 @@
|
|||
chapter.</para>
|
||||
</section>
|
||||
<section xml:id="nsa-request-cache">
|
||||
<title>The <literal>request-cache</literal> Element</title>
|
||||
<title>The <literal><request-cache></literal> Element</title>
|
||||
<para>Sets the <interfacename>RequestCache</interfacename> instance which will be used
|
||||
by the <classname>ExceptionTranslationFilter</classname> to store request
|
||||
information before invoking an
|
||||
<interfacename>AuthenticationEntryPoint</interfacename>. </para>
|
||||
</section>
|
||||
<section>
|
||||
<title>The <literal><http-firewall></literal> Element</title>
|
||||
<para>This is a top-level element which can be used to inject a custom implementation of
|
||||
<interfacename>HttpFirewall</interfacename> into the
|
||||
<classname>FilterChainProxy</classname> created by the namespace. The default
|
||||
implementation should be suitable for most applications.</para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="nsa-authentication">
|
||||
<title>Authentication Services</title>
|
||||
|
|
Loading…
Reference in New Issue