Spring 过滤器
Spring Security用到了很多过滤器,参考指南的后续部分会一一提到。 如果你使用了命名空间配置,你就不用经常去明确指定过滤器bean。 有几种可能情况,你希望对安全过滤器链进行完全控制,或许因为你使用的功能没法使用命名空间进行支持,或者你使用了自己自定义版本的类。
这种情况下,你可以选择向你的web应用成立里添加哪些过滤器,这里你可以使用Spring的DelegatingFilterProxy或 FilterChainProxy。我们会在下面介绍它们两个。
在使用DelegatingFilterProxy的时候,你会看到web.xml里这样的内容:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意这个过滤器其实是一个DelegatingFilterProxy,这个过滤器里没有实现过滤器的任何逻辑。 DelegatingFilterProxy做的事情是代理Filter的方法,从application context里获得bean。 这让bean可以获得spring web application context的生命周期支持,使配置较为轻便。 bean必须实现javax.servlet.Filter接口,它必须和filter-name里定义的名称是一样的。
在生命周期的问题上,要考虑在IoC容器里而不是在servlet容器里管理Filter。 具体来说,到底是哪个容器应该调用Filter的“启动”与“关闭”方法。 需要指出的是Filter的初始化和销毁很容易受servlet容器的影响,如果一个Filter依赖于较早初始化Filter的配置,那么可能会引发一些问题。 Spring IoC容器,从另一方面讲,拥有更强大的生命周期/IoC接口(比如InitializingBean, DisposableBean, BeanNameAware, ApplicationContextAware和很多其他的),拥有更容易理解的接口协议,可预见的方法调用顺序,支持自动绑定,更可以选择不用实现Spring的接口(比如通过Spring XML中的destroy-method属性)。 介于这些原因,只要有可能的话,我们推荐使用Spring生命周期服务,代替servlet容器的生命周期。 可以参考DelegatingFilterProxy的Javadoc获得更多信息。
最好别用DelegatingFilterProxy,我们强烈推荐你使用FilterChainProxy代替它。 虽然DelegatingFilterProxy是一个非常有用的类,问题是在需要使用几个过滤器的时候,需要在web.xml中定义<filter>和<filter-mapping>入口的代码数量太多了。 为了解决这个问题,Spring Security提供了一个FilterChainProxy类。 它绑定了一个DelegatingFilterProxy(好像上面的例子那样),但是使用的类是org.springframework.security.util.FilterChainProxy。 过滤器链要声明在application context里,使用下面的代码:
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**"
filters="httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
<sec:filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
</sec:filter-chain-map>
</bean>
你可能注意到FilterSecurityInterceptor声明的不同方式。 它同时支持正则表达式和ant路径,并且只使用第一个出现的匹配URI。 在运行阶段FilterChainProxy会定位当前web请求匹配的第一个URI模式。 每个与bean相关的配置属性,都定义在application context中。 这些过滤器会按照它们指定的顺序依次调用,使用标准的FilterChain预期行为(如果一个Filter希望中止过滤器连,就可以决定不继续执行)。
你可以看到,FilterChainProxy需要在不同的请求模式中重复引用过滤器的名称(如上例exceptionTranslationFilter 和 filterSecurityInterceptor都重复使用了)。 这个设计思路是让FilterChainProxy可以为不同的URI模式,指定不同的Filter顺序,也可以提升表现(使用正则表达式,ant路径,和其他自定义FilterInvocationDefinitionSource实现),也能弄清楚哪个 Filter应该被调用。
你可能注意到了,我们在过滤器链里声明了两个HttpSessionContextIntegrationFilter(ASC是allowSessionCreation的简写,是HttpSessionContextIntegrationFilter的一个属性)。 因为web服务从来不会在请求里带上jsessionid,为每个用户代理都创建一个HttpSession完全是一种浪费。 如果你需要构建一个高等级最高可扩展性的系统,我们推荐你使用上面的配置方法。 对于小一点儿的项目,使用一个HttpSessionContextIntegrationFilter(让它的allowSessionCreation默认为true)就足够了。
在有关声明周期的问题上,如果这些方法被FilterChainProxy自己调用,FilterChainProxy会始终根据下一层的Filter代理init(FilterConfig)和destroy()方法。 这时,FilterChainProxy会保证初始化和销毁操作只会在Filter上调用一次,而不管它们被FilterInvocationDefinitionSource声明了多少次。 你可以完全控制是否调用这些方法,通过代理DelegatingFilterProxy的targetFilterLifecycle初始化参数,。 像上面讨论的那样,默认的servlet容器生命周期调用不会被DelegatingFilterProxy代理。
同样的,我们可以使用filters = "none"属性,在使用命名空间配置的时候,你可以忽略过滤器链中的一个URI模式,在<URI Pattern> = <Filter Chain>表达式的右手侧使用 #NONE#标志。 比如,使用上边的例子,如果你想排除完全/webservices部分,你可以把bean声明的相关那行修改成这样。
/webServices/**=#NONE#
注意,任何匹配这个路径的请求,不会要求认证,不会使用验证服务,可以自由的访问。
定义在web.xml里的过滤器的顺序是非常重要的。 不论你实际使用的是哪个过滤器,<filter-mapping>的顺序应该像下面这样:
1. ChannelProcessingFilter,因为它可能需要重定向到其他协议。
2. ConcurrentSessionFilter,因为它不使用SecurityContextHolder功能,但是需要更新 SessionRegistry 来从主体中放映正在进行的请求。
3. HttpSessionContextIntegrationFilter,这样 SecurityContext可以在web请求的开始阶段通过 SecurityContextHolder建立,然后 SecurityContext的任何修改都会在web请求结束的时候(为下一个web请求做准备)复制到 HttpSession中。
4. 验证执行机制 - AuthenticationProcessingFilter, CasProcessingFilter, BasicProcessingFilter, HttpRequestIntegrationFilter, JbossIntegrationFilter 等等 - 这样 SecurityContextHolder 可以被修改,并包含一个合法的 Authentication 请求标志。
5.SecurityContextHolderAwareRequestFilter,如果,你使用它,把一个Spring Security提醒HttpServletRequestWrapper安装到你的servlet容器里。
6. RememberMeProcessingFilter,这样如果之前的验证执行机制没有更新 SecurityContextHolder,这个请求提供了一个可以使用的remember-me服务的cookie,一个对应的已保存的 Authentication对象会被创建出来。
7. AnonymousProcessingFilter,这样如果之前的验证执行机制没有更新 SecurityContextHolder,会创建一个匿名 Authentication对象。
8. ExceptionTranslationFilter,用来捕捉 Spring Security异常,这样,可能返回一个HTTP错误响应,或者执行一个对应的 AuthenticationEntryPoint。
9. FilterSecurityInterceptor,保护web URI。
上面所有的过滤器,都使用了 DelegatingFilterProxy 或 FilterChainProxy。推荐使用单独的 DelegatingFilterProxy 为每个程序代理一个单独的 FilterChainProxy,通过这个 FilterChainProxy 定义Spring Security的所有过滤器。
如果你使用了SiteMesh,一定要确保Spring Security过滤器在SiteMesh的过滤器之前被调用。 这才可以保证为SiteMesh渲染器使用的 SecurityContextHolder 先被组装起来。
分享到:
相关推荐
### Spring管理Filter与Servlet详解 在现代Web应用开发中,Spring框架因其强大的依赖注入和面向切面编程功能而被广泛采用。特别是在Java EE环境中,如何有效地整合Spring与Servlet、Filter等核心组件,对于构建高...
Spring注入Filter与Listener的方法.png
总结,这个"过滤器 spring4.1+jdk1.7版本"的压缩包提供了一个学习和实践Spring Filter和Interceptor的平台,通过分析和运行其中的代码,开发者可以深入理解这两种机制在Java Web开发中的应用和重要性。同时,对于...
Spring框架提供了多种机制来增强应用程序的功能,其中之一就是过滤器(Filter)。本篇将深入探讨"Spring过滤器",以及如何利用它来实现网站的过滤功能。 首先,过滤器是Java Servlet规范的一部分,用于在请求被...
本篇我们将深入探讨如何在Spring Security中自定义Filter,以及相关的知识点。 首先,我们需要了解Spring Security的Filter工作原理。Spring Security的过滤器链是由`DelegatingFilterProxy`管理的,它会委托给`...
### web.xml文件中配置(servlet, spring, filter, listener)的加载顺序 在Java Web应用开发中,`web.xml`文件是整个Web应用程序的核心配置文件之一,它定义了Servlet容器如何启动、初始化以及配置各个组件如...
默认情况下,Spring Boot的内置Filter会先执行,然后是用户自定义的Filter。 总结,Spring Boot的过滤器机制提供了强大的请求处理能力,开发者可以根据需求创建并配置过滤器,实现各种定制化的操作。通过合理利用...
在开发基于Spring MVC的Web应用程序时,正确配置所需的jar包和Filter是至关重要的步骤。Spring MVC是一个强大的MVC(Model-View-Controller)框架,它为构建Java Web应用提供了丰富的功能和灵活性。以下是对标题和...
《Spring Security 深度解析:以securityfilter-spring为例》 在当今信息化社会,网络安全已经成为企业及个人数据保护的重中之重。Spring Security作为Spring生态体系中的一个重要组件,为Java应用程序提供了强大的...
Spring4 In Action-7.1.2-添加其他的Servlet和Filter,Spring4 In Action-7.1.2-添加其他的Servlet和Filter,Spring4 In Action-7.1.2-添加其他的Servlet和Filter
本篇将详细讲解如何利用Spring解决跨域问题,以及如何使用`cors-filter-1.7.jar`和`java-property-utils-1.9.1.jar`这两个库来辅助实现。 一、Spring解决跨域问题的基本原理 1. CORS定义:跨域是指浏览器遵循同源...
3. **定制Filter**:在Spring Cloud Gateway中,我们可以自定义WebFlux Filter,利用Spring Security提供的API进行认证和鉴权。这通常涉及到`@PreAuthorize`和`@Secured`等注解的使用,以控制对特定路由的访问权限。...
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/* </filter-mapping...
在本文中,我们将深入探讨如何在Spring Boot应用中使用拦截器(Interceptor)和过滤器(Filter)来处理用户的登录session。这两个组件都是Spring框架的重要部分,它们在处理HTTP请求和响应时发挥着关键作用。 首先...
org.springframework.web.filter.Log4jNestedDiagnosticContextFilter.class org.springframework.web.filter.OncePerRequestFilter.class org.springframework.web.filter.RequestContextFilter.class org.spring...
- **Spring Filter**:Spring框架提供了多种过滤器,如`DelegatingFilterProxy`,可以代理到Spring的Bean,实现AOP切面过滤。 4. **Spring MVC中的Filter** - **Spring MVC与Filter**:Spring MVC是Spring框架的...
- **Spring Security 定义好的核心Filter**:包括一系列内置过滤器,如`UsernamePasswordAuthenticationFilter`等。 ##### 10. **退出登录** - **概念**:提供了退出登录的功能,清除用户的认证状态。 ##### 11. ...
此外,它还提供了对Servlet、Filter和Listener的集成,使得Spring能够与任何Servlet容器(如Tomcat、Jetty)无缝协作。WebSocket API的集成则允许开发者创建实时双向通信的应用。 Spring Web MVC模块(spring-web...
6. **Web安全(Web Security)**:对于基于Servlet的应用,Spring Security通过Servlet Filter进行安全控制;对于响应式(Reactive)应用,它提供了WebFlux安全支持,利用Reactor库处理非阻塞的HTTP请求。 7. **API...
1. **Filter Chain**: Spring Security通过一系列过滤器(Filter)来实现其安全功能。这些过滤器按照特定顺序执行,形成一个Filter Chain,处理HTTP请求。 2. **Authentication**: 身份验证是指确认用户的身份。...