Made servlet-api integration into an attribute of http, rather than a child element since it has no configuration.

This commit is contained in:
Luke Taylor 2007-12-20 17:51:27 +00:00
parent 1c9bd8bf5f
commit 85b10f79c2
6 changed files with 81 additions and 93 deletions

View File

@ -25,7 +25,6 @@ class Elements {
public static final String REMEMBER_ME = "remember-me"; public static final String REMEMBER_ME = "remember-me";
public static final String ANONYMOUS = "anonymous"; public static final String ANONYMOUS = "anonymous";
public static final String FILTER_CHAIN = "filter-chain"; public static final String FILTER_CHAIN = "filter-chain";
public static final String SERVLET_API_INTEGRATION = "servlet-api-integration";
public static final String ANNOTATION_DRIVEN = "annotation-driven"; public static final String ANNOTATION_DRIVEN = "annotation-driven";
} }

View File

@ -16,6 +16,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext; import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.ConfigAttributeDefinition; import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor; import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.context.HttpSessionContextIntegrationFilter; import org.springframework.security.context.HttpSessionContextIntegrationFilter;
import org.springframework.security.intercept.web.AbstractFilterInvocationDefinitionSource; import org.springframework.security.intercept.web.AbstractFilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterInvocationDefinitionMap; import org.springframework.security.intercept.web.FilterInvocationDefinitionMap;
@ -69,6 +70,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
static final String ATT_AUTO_CONFIG = "auto-config"; static final String ATT_AUTO_CONFIG = "auto-config";
static final String DEF_AUTO_CONFIG = "false"; static final String DEF_AUTO_CONFIG = "false";
static final String ATT_SERVLET_API_PROVISION = "servlet-api-provision";
static final String DEF_SERVLET_API_PROVISION = "true";
public BeanDefinition parse(Element element, ParserContext parserContext) { public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class); RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class);
RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class); RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
@ -121,6 +125,16 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
channelFilterInvDefSource.setConvertUrlToLowercaseBeforeComparison(false); channelFilterInvDefSource.setConvertUrlToLowercaseBeforeComparison(false);
} }
// Add servlet-api integration filter if required
String provideServletApi = element.getAttribute(ATT_SERVLET_API_PROVISION);
if (!StringUtils.hasText(provideServletApi)) {
provideServletApi = DEF_SERVLET_API_PROVISION;
}
if ("true".equals(provideServletApi)) {
parserContext.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER,
new RootBeanDefinition(SecurityContextHolderAwareRequestFilter.class));
}
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap); filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource); filterSecurityInterceptorBuilder.addPropertyValue("objectDefinitionSource", interceptorFilterInvDefSource);
@ -190,11 +204,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext); new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext);
} }
Element servletApiIntegrationElt = DomUtils.getChildElementByTagName(element, Elements.SERVLET_API_INTEGRATION);
if (servletApiIntegrationElt != null || autoConfig) {
new ServletApiIntegrationBeanDefinitionParser().parse(servletApiIntegrationElt, parserContext);
}
registry.registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy); registry.registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy);
registry.registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif); registry.registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
registry.registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition()); registry.registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition());

View File

@ -1,25 +0,0 @@
package org.springframework.security.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter;
import org.w3c.dom.Element;
/**
* @author Ben Alex
* @version $Id$
*/
public class ServletApiIntegrationBeanDefinitionParser implements BeanDefinitionParser {
protected final Log logger = LogFactory.getLog(getClass());
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinition filter = new RootBeanDefinition(SecurityContextHolderAwareRequestFilter.class);
parserContext.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER, filter);
System.out.println("********************");
return null;
}
}

View File

@ -8,8 +8,6 @@ default namespace = "http://www.springframework.org/schema/security"
start = http | ldap | repository start = http | ldap | repository
# targetNamespace="http://www.springframework.org/schema/security"
hash = hash =
## Defines the type of hashing used on user passwords. If unspecified, "plaintext" is nominated, which indicates that the passwords are not hashed. We recommend strongly against using MD4, as it is a very weak hashing algorithm. ## Defines the type of hashing used on user passwords. If unspecified, "plaintext" is nominated, which indicates that the passwords are not hashed. We recommend strongly against using MD4, as it is a very weak hashing algorithm.
attribute hash {"plaintext" | "sha-hex" | "sha-base64" | "md5-hex" | "md5-base64" | "md4-hex" | "md4-base64"} attribute hash {"plaintext" | "sha-hex" | "sha-base64" | "md5-hex" | "md5-base64" | "md4-hex" | "md4-base64"}
@ -65,7 +63,7 @@ annotation-driven.attlist = empty
http = http =
## Container element for HTTP security configuration ## Container element for HTTP security configuration
element http {http.attlist, (intercept-url+ & form-login? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous? & servlet-api-integration?) } element http {http.attlist, (intercept-url+ & form-login? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous?) }
http.attlist &= http.attlist &=
## Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. If set to "true", all of these capabilities are added (although you can still customize the configuration of each by providing the respective element). If unspecified, defaults to "false". ## Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. If set to "true", all of these capabilities are added (although you can still customize the configuration of each by providing the respective element). If unspecified, defaults to "false".
attribute auto-config {"true" | "false" }? attribute auto-config {"true" | "false" }?
@ -78,6 +76,9 @@ http.attlist &=
http.attlist &= http.attlist &=
## Whether test URLs should be converted to lower case prior to comparing with defined path patterns. If unspecified, defaults to "true". ## Whether test URLs should be converted to lower case prior to comparing with defined path patterns. If unspecified, defaults to "true".
attribute lowercase-comparisons {"true" | "false"}? attribute lowercase-comparisons {"true" | "false"}?
http.attlist &=
## Provides versions of HttpServletRequest security methods such as isUserInRole() and getPrincipal() which are implemented by accessing the Spring SecurityContext. Defaults to "true".
attribute servlet-api-provision {"true" | "false"}?
http.attlist &= http.attlist &=
## Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests. ## Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests.
attribute access-decision-manager {xsd:string}? attribute access-decision-manager {xsd:string}?
@ -165,10 +166,6 @@ remember-me =
remember-me.attlist &= remember-me.attlist &=
(attribute key {xsd:string} | (attribute token-repository {xsd:string} | attribute data-source {xsd:string})) (attribute key {xsd:string} | (attribute token-repository {xsd:string} | attribute data-source {xsd:string}))
servlet-api-integration =
element servlet-api-integration {servlet-api-integration.attlist}
servlet-api-integration.attlist = empty
anonymous = anonymous =
## Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority. ## Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority.
element anonymous {anonymous.attlist} element anonymous {anonymous.attlist}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.springframework.org/schema/security" xmlns:security="http://www.springframework.org/schema/security"> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.springframework.org/schema/security" xmlns:security="http://www.springframework.org/schema/security">
<!-- targetNamespace="http://www.springframework.org/schema/security" -->
<xs:attributeGroup name="hash"> <xs:attributeGroup name="hash">
<xs:attribute name="hash" use="required"> <xs:attribute name="hash" use="required">
<xs:annotation> <xs:annotation>
@ -35,7 +34,7 @@
<xs:attributeGroup name="port"> <xs:attributeGroup name="port">
<xs:attribute name="port" use="required" type="xs:integer"> <xs:attribute name="port" use="required" type="xs:integer">
<xs:annotation> <xs:annotation>
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP server, for example. </xs:documentation> <xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP server, for example.</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
</xs:attributeGroup> </xs:attributeGroup>
@ -62,7 +61,7 @@
</xs:attribute> </xs:attribute>
<xs:attribute name="port" type="xs:integer"> <xs:attribute name="port" type="xs:integer">
<xs:annotation> <xs:annotation>
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP server, for example. </xs:documentation> <xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP server, for example.</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="ldif" default="classpath:*.ldif" type="xs:string"> <xs:attribute name="ldif" default="classpath:*.ldif" type="xs:string">
@ -92,7 +91,7 @@
<xs:attributeGroup name="protect.attlist"> <xs:attributeGroup name="protect.attlist">
<xs:attribute name="method" use="required" type="xs:string"> <xs:attribute name="method" use="required" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation>A method name </xs:documentation> <xs:documentation>A method name</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="access" use="required" type="xs:string"> <xs:attribute name="access" use="required" type="xs:string">
@ -120,7 +119,6 @@
<xs:element ref="security:concurrent-session-control"/> <xs:element ref="security:concurrent-session-control"/>
<xs:element ref="security:remember-me"/> <xs:element ref="security:remember-me"/>
<xs:element ref="security:anonymous"/> <xs:element ref="security:anonymous"/>
<xs:element ref="security:servlet-api-integration"/>
</xs:choice> </xs:choice>
<xs:attributeGroup ref="security:http.attlist"/> <xs:attributeGroup ref="security:http.attlist"/>
</xs:complexType> </xs:complexType>
@ -171,6 +169,17 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="servlet-api-provision">
<xs:annotation>
<xs:documentation>Provides versions of HttpServletRequest security methods such as isUserInRole() and getPrincipal() which are implemented by accessing the Spring SecurityContext. Defaults to "true".</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
<xs:enumeration value="false"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="access-decision-manager" type="xs:string"> <xs:attribute name="access-decision-manager" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation>Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests.</xs:documentation> <xs:documentation>Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests.</xs:documentation>
@ -193,7 +202,7 @@
<xs:attributeGroup name="intercept-url.attlist"> <xs:attributeGroup name="intercept-url.attlist">
<xs:attribute name="pattern" use="required" type="xs:string"> <xs:attribute name="pattern" use="required" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation>The pattern which defines the URL path. The content will depend on the type set in the containing http element, so will default to ant path syntax. </xs:documentation> <xs:documentation>The pattern which defines the URL path. The content will depend on the type set in the containing http element, so will default to ant path syntax.</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="access" type="xs:string"> <xs:attribute name="access" type="xs:string">
@ -346,9 +355,6 @@
<xs:attribute name="token-repository" type="xs:string"/> <xs:attribute name="token-repository" type="xs:string"/>
<xs:attribute name="data-source" type="xs:string"/> <xs:attribute name="data-source" type="xs:string"/>
</xs:attributeGroup> </xs:attributeGroup>
<xs:element name="servlet-api-integration">
<xs:complexType/>
</xs:element>
<xs:element name="anonymous"> <xs:element name="anonymous">
<xs:annotation> <xs:annotation>
<xs:documentation>Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority.</xs:documentation> <xs:documentation>Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority.</xs:documentation>
@ -365,7 +371,7 @@
</xs:attribute> </xs:attribute>
<xs:attribute name="username" type="xs:string"> <xs:attribute name="username" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation>The username that should be assigned to the anonymous request. This allows the principal to be identified, which may be important for logging and auditing. if unset, defaults to "anonymousUser". </xs:documentation> <xs:documentation>The username that should be assigned to the anonymous request. This allows the principal to be identified, which may be important for logging and auditing. if unset, defaults to "anonymousUser".</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="granted-authority" type="xs:string"> <xs:attribute name="granted-authority" type="xs:string">
@ -445,7 +451,7 @@
</xs:attribute> </xs:attribute>
<xs:attribute name="authorities" use="required" type="xs:string"> <xs:attribute name="authorities" use="required" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation>One of more authorities granted to the user. Separate authorities with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR" </xs:documentation> <xs:documentation>One of more authorities granted to the user. Separate authorities with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR"</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
</xs:attributeGroup> </xs:attributeGroup>

View File

@ -11,6 +11,7 @@ import org.springframework.security.ui.rememberme.RememberMeProcessingFilter;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter; import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter; import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter;
import org.springframework.security.util.FilterChainProxy; import org.springframework.security.util.FilterChainProxy;
import org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.junit.AfterClass; import org.junit.AfterClass;
@ -58,7 +59,7 @@ public class HttpSecurityBeanDefinitionParserTests {
List filterList = filterChainProxy.getFilters("/someurl"); List filterList = filterChainProxy.getFilters("/someurl");
assertEquals("Expected 10 filters in chain", 10, filterList.size()); assertEquals("Expected 11 filters in chain", 11, filterList.size());
Iterator filters = filterList.iterator(); Iterator filters = filterList.iterator();
@ -69,6 +70,7 @@ public class HttpSecurityBeanDefinitionParserTests {
assertTrue(filters.next() instanceof AuthenticationProcessingFilter); assertTrue(filters.next() instanceof AuthenticationProcessingFilter);
assertTrue(filters.next() instanceof DefaultLoginPageGeneratingFilter); assertTrue(filters.next() instanceof DefaultLoginPageGeneratingFilter);
assertTrue(filters.next() instanceof BasicProcessingFilter); assertTrue(filters.next() instanceof BasicProcessingFilter);
assertTrue(filters.next() instanceof SecurityContextHolderAwareRequestFilter);
assertTrue(filters.next() instanceof RememberMeProcessingFilter); assertTrue(filters.next() instanceof RememberMeProcessingFilter);
assertTrue(filters.next() instanceof ExceptionTranslationFilter); assertTrue(filters.next() instanceof ExceptionTranslationFilter);
assertTrue(filters.next() instanceof FilterSecurityInterceptor); assertTrue(filters.next() instanceof FilterSecurityInterceptor);