Add namespace support for Servlet API integration.

This commit is contained in:
Ben Alex 2007-12-04 12:23:41 +00:00
parent a205f95c19
commit 85085abf9e
11 changed files with 86 additions and 46 deletions

View File

@ -34,7 +34,6 @@ public class BeanIds {
public static final String REMEMBER_ME_FILTER = "_rememberMeFilter";
public static final String REMEMBER_ME_SERVICES = "_rememberMeServices";
public static final String DEFAULT_LOGIN_PAGE_GENERATING_FILTER = "_defaultLoginPageFilter";
public static final String SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER = "_securityContextHolderAwareRequestFilter";
}

View File

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

View File

@ -190,12 +190,16 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
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.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
registry.registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition());
registry.registerBeanDefinition(BeanIds.FILTER_SECURITY_INTERCEPTOR, filterSecurityInterceptorBuilder.getBeanDefinition());
// Register the post processor which will tie up the loose ends in the configuration once the app context has been created and all beans are available.
registry.registerBeanDefinition("__httpConfigBeanFactoryPostProcessor", new RootBeanDefinition(HttpSecurityConfigPostProcessor.class));

View File

@ -0,0 +1,25 @@
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

@ -15,23 +15,20 @@
package org.springframework.security.wrapper;
import org.springframework.security.util.PortResolver;
import org.springframework.security.util.PortResolverImpl;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.io.IOException;
import java.lang.reflect.Constructor;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.ui.FilterChainOrderUtils;
import org.springframework.security.ui.SpringSecurityFilter;
import org.springframework.security.util.PortResolver;
import org.springframework.security.util.PortResolverImpl;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
@ -47,7 +44,7 @@ import javax.servlet.http.HttpServletRequest;
* @author Ben Alex
* @version $Id$
*/
public class SecurityContextHolderAwareRequestFilter implements Filter {
public class SecurityContextHolderAwareRequestFilter extends SpringSecurityFilter {
//~ Instance fields ================================================================================================
private Class wrapperClass = SavedRequestAwareWrapper.class;
@ -57,12 +54,23 @@ public class SecurityContextHolderAwareRequestFilter implements Filter {
//~ Methods ========================================================================================================
public void destroy() {}
public void setPortResolver(PortResolver portResolver) {
Assert.notNull(portResolver, "PortResolver required");
this.portResolver = portResolver;
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
public void setWrapperClass(Class wrapperClass) {
Assert.notNull(wrapperClass, "WrapperClass required");
Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), "Wrapper must be a HttpServletRequest");
this.wrapperClass = wrapperClass;
}
public void setRolePrefix(String rolePrefix) {
Assert.notNull(rolePrefix, "Role prefix must not be null");
this.rolePrefix = rolePrefix.trim();
}
protected void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!wrapperClass.isAssignableFrom(request.getClass())) {
if (constructor == null) {
try {
@ -80,24 +88,10 @@ public class SecurityContextHolderAwareRequestFilter implements Filter {
}
}
filterChain.doFilter(request, servletResponse);
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {}
public void setPortResolver(PortResolver portResolver) {
Assert.notNull(portResolver, "PortResolver required");
this.portResolver = portResolver;
}
public void setWrapperClass(Class wrapperClass) {
Assert.notNull(wrapperClass, "WrapperClass required");
Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), "Wrapper must be a HttpServletRequest");
this.wrapperClass = wrapperClass;
}
public void setRolePrefix(String rolePrefix) {
Assert.notNull(rolePrefix, "Role prefix must not be null");
this.rolePrefix = rolePrefix.trim();
}
public int getOrder() {
return FilterChainOrderUtils.SECURITY_CONTEXT_HOLDER_AWARE_FILTER_ORDER;
}
}

View File

@ -57,9 +57,9 @@ protect.attlist &=
http =
## Container element for HTTP security configuration
element http {http.attlist, (intercept-url+ & form-login? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous?) }
element http {http.attlist, (intercept-url+ & form-login? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous? & servlet-api-integration?) }
http.attlist &=
## Automatically registers a login form, BASIC authentication, anonymous authentication, logout services and remember-me. 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 autoConfig {"true" | "false" }?
http.attlist &=
## Controls the eagerness with which an HTTP session is created. If not set, defaults to "ifRequired".
@ -157,6 +157,10 @@ remember-me =
remember-me.attlist &=
(attribute key {xsd:string} | (attribute tokenRepository {xsd:string} | attribute datasource {xsd:string}))
servlet-api-integration =
element servlet-api-integration {servlet-api-integration.attlist}
servlet-api-integration.attlist = empty
anonymous =
## Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority.
element anonymous {anonymous.attlist}

View File

@ -114,6 +114,7 @@
<xs:element ref="security:concurrent-session-control"/>
<xs:element ref="security:remember-me"/>
<xs:element ref="security:anonymous"/>
<xs:element ref="security:servlet-api-integration"/>
</xs:choice>
<xs:attributeGroup ref="security:http.attlist"/>
</xs:complexType>
@ -121,7 +122,7 @@
<xs:attributeGroup name="http.attlist">
<xs:attribute name="autoConfig">
<xs:annotation>
<xs:documentation>Automatically registers a login form, BASIC authentication, anonymous authentication, logout services and remember-me. 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".</xs:documentation>
<xs:documentation>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".</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
@ -339,6 +340,9 @@
<xs:attribute name="tokenRepository" type="xs:string"/>
<xs:attribute name="datasource" type="xs:string"/>
</xs:attributeGroup>
<xs:element name="servlet-api-integration">
<xs:complexType/>
</xs:element>
<xs:element name="anonymous">
<xs:annotation>
<xs:documentation>Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority.</xs:documentation>

View File

@ -20,6 +20,7 @@ import junit.framework.TestCase;
import org.springframework.security.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.io.IOException;
@ -54,11 +55,11 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase {
public void testCorrectOperation() throws Exception {
SecurityContextHolderAwareRequestFilter filter = new SecurityContextHolderAwareRequestFilter();
filter.init(new MockFilterConfig());
filter.doFilter(new MockHttpServletRequest(null, null), null,
filter.doFilter(new MockHttpServletRequest(null, null), new MockHttpServletResponse(),
new MockFilterChain(SavedRequestAwareWrapper.class));
// Now re-execute the filter, ensuring our replacement wrapper is still used
filter.doFilter(new MockHttpServletRequest(null, null), null,
filter.doFilter(new MockHttpServletRequest(null, null), new MockHttpServletResponse(),
new MockFilterChain(SavedRequestAwareWrapper.class));
filter.destroy();

View File

@ -23,8 +23,9 @@
<http-basic />
<logout />
<remember-me />
<servlet-api-integration/>
-->
<concurrent-session-control maxSessions="1" exceptionIfMaximumExceeded="true"/>
</http>

View File

@ -1,7 +1,9 @@
<html>
<body>
<h1>Home Page</h1>
Anyone can view this page.
Anyone can view this page.<br><br>
Your principal object is....: <%= request.getUserPrincipal() %><br><br>
<p><a href="secure/index.jsp">Secure page</a>
<p><a href="secure/extreme/index.jsp">Extremely secure page</a>

View File

@ -2,7 +2,12 @@
<body>
<h1>Secure Page</h1>
This is a protected page. You can get to me if you've been remembered,
or if you've authenticated this session.
or if you've authenticated this session.<br><br>
<%if (request.isUserInRole("ROLE_SUPERVISOR")) { %>
You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br><br>
<% } %>
<p><a href="../">Home</a>
<p><a href="../j_spring_security_logout">Logout</a>