瀏覽代碼

Add namespace support for Servlet API integration.

Ben Alex 18 年之前
父節點
當前提交
85085abf9e

+ 1 - 2
core/src/main/java/org/springframework/security/config/BeanIds.java

@@ -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";
 	
 }

+ 1 - 0
core/src/main/java/org/springframework/security/config/Elements.java

@@ -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";
 
 }

+ 5 - 1
core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java

@@ -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));
 

+ 25 - 0
core/src/main/java/org/springframework/security/config/ServletApiIntegrationBeanDefinitionParser.java

@@ -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;
+    }
+}

+ 29 - 35
core/src/main/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilter.java

@@ -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);
-    }
-
-    public void init(FilterConfig filterConfig) throws ServletException {}
-
-    public void setPortResolver(PortResolver portResolver) {
-        Assert.notNull(portResolver, "PortResolver required");
-        this.portResolver = portResolver;
-    }
+        chain.doFilter(request, response);
+	}
 
-    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;
+	}
 }

+ 6 - 2
core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc

@@ -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} 

+ 5 - 1
core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd

@@ -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>

+ 3 - 2
core/src/test/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilterTests.java

@@ -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();

+ 2 - 1
samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security-ns.xml

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

+ 3 - 1
samples/tutorial/src/main/webapp/index.jsp

@@ -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>

+ 6 - 1
samples/tutorial/src/main/webapp/secure/index.jsp

@@ -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>