`
jaw111
  • 浏览: 31021 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论
阅读更多

                                                               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 先被组装起来。

分享到:
评论
1 楼 leaon 2013-01-04  
在Spring配置文件里定义了filterChainProxy了之后,在哪里引用它呢?

相关推荐

    Spring 管理filter 和servlet

    Spring 管理filter 和servlet

    Spring注入Filter与Listener的方法.png

    Spring注入Filter与Listener的方法.png

    spring-boot 过滤器 filter

    spring-boot 过滤器 filter spring-boot 过滤器 filter

    Spring4 In Action-7.1.2-添加其他的Servlet和Filter

    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 Cloud.docx

    Spring Cloud(七)服务网关 Zuul Filter 使用 spring-cloud-config Spring Cloud(八)高可用的分布式配置中心 Spring Cloud Config ring-cloud-config-eureka Spring Cloud(九)高可用的分布式配置...

    spring-web-2.5.jar

    org.springframework.web.filter.Log4jNestedDiagnosticContextFilter.class org.springframework.web.filter.OncePerRequestFilter.class org.springframework.web.filter.RequestContextFilter.class org.spring...

    spring jar 包详解

    (11) spring-web.jar 这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、 Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 (12) ...

    springsecurity2 自定义filter实现

    NULL 博文链接:https://jiawu.iteye.com/blog/400351

    securityfilter-spring

    基于spring2.5,securityfilter-2.0是spring最新推出的安全认证工具之一,可以很好的处理用户登录认证,xml文件化的配置方式。

    web.xml文件中配置(servlet, spring, filter, listenr)的加载顺序

    java servlet spring web filter listenr

    spring MVC所需jar包和filter的配置

    spring MVC所需jar包和filter的配置,jar包下载后可以直接使用,而filter的代码和配置可以参考使用

    spring-boot-filter:一个简单的Spring Boot过滤器数据示例

    弹簧靴过滤器 这是在Spring Boot中将过滤器与外部库一起使用的示例 通过mvn clean spring-boot:run运行此仓库 显示所有数据: http://localhost:8080/customers 按单个属性过滤 ... 按多个属性过滤 ...

    SpringSecurity项目

    springsecurity是一个功能强大且高度可定制的身份验证和访问控制框架。springsecurity是一个...最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。

    spring4.1核心包

    包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 18. spring-webmvc-4.1.1.RELEASE.jar 包含...

    spring-web-5.3.6 jar包.rar

    这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类, 包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 spring的核心类,提供了核心HTTP...

    Spring Security实战源码

    ssecurity-customFilter项目是Spring Security实战(六)的源码; ssecurity-rememberMe项目是Spring Security实战(七)的源码; 本人开发工具是IDEA,每个项目中的代码均可以运行并测试。Eclipse也是一样可以运行...

    spring配置编码格式

    org.springframework.web.filter.CharacterEncodingFilter &lt;/filter-class&gt; &lt;param-name&gt;encoding &lt;param-value&gt;UTF-8 &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;setCharacterEncoding&lt;/filter-name&gt; ...

    多线程实现脏字及不和谐文字的过滤(高效)

    很高效啊 三十万个关键字过滤 一秒钟搞定

    Spring MVC 入门实例

    22 &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt; 23 24 &lt;param-name&gt;encoding 25 &lt;param-value&gt;UTF-8 26 27 &lt;/filter&gt; 28 29 &lt;filter-mapping&gt; 30 &lt;filter-name&gt;...

    spring-cloud使用的各种示例

    - [spring-cloud-zuul](https://github.com/ityouknow/spring-cloud-examples/tree/master/spring-cloud-zuul):Spring Cloud Zuul使用高级篇 Filter 鉴权 熔断 重试 - [spring-cloud-sleuth-zipkin]...

Global site tag (gtag.js) - Google Analytics