`
阅读更多
Spring Security的web架构是完全基于标准的servlet过滤器的。 它没有在内部使用servlet或任何其他基于servlet的框架(比如spring mvc), 所以它没有与任何特定的web技术强行关联。 它只管处理HttpServletRequest 和HttpServletResponse,不关心请求时来自浏览器,web服务客户端,HttpInvoker还是一个AJAX应用。
Spring Security维护了一个过滤器链,每个过滤器拥有特定的功能,过滤器需要服务也会对应添加和删除。 过滤器的次序是非常重要的,它们之间都有依赖关系。 如果你已经使用了命名空间配置,过滤器会自动帮你配置, 你不需要定义任何Spring Bean,但是有时候你需要完全控制Spring过滤器链, 因为你使用了命名空间没有提供的特性,或者你需要使用你自己自定义的类。
7.1. DelegatingFilterProxy
当使用servlet过滤器时,你很需要在你的web.xml中声明它们, 它们可能被servlet容器忽略。在Spring Security,过滤器类也是定义在xml中的spring bean, 因此可以获得Spring的依赖注入机制和生命周期接口。 spring的DelegatingFilterProxy提供了在 web.xml和application context之间的联系。
当使用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里定义的名称是一样的。查看DelegatingFilterProxy的javadoc获得更多信息。
7.2. FilterChainProxy
现在应该清楚了,你可以声明每个Spring Security过滤器bean,你在application context中需要的。 把一个DelegatingFilterProxy入口添加到web.xml, 确认它们的次序是正确的。 这是一种繁琐的方式,会让web.xml显得十分杂乱,如果我们配置了太多过滤器的话。 我们最好添加一个单独的入口,在web.xml中,然后在application context中处理实体, 管理我们的web安全bean。 这就是FilterChainProxy所做的事情。它使用DelegatingFilterProxy (就像上面例子中那样),但是对应的class是org.springframework.security.web.FilterChainProxy。 过滤器链是在application context中声明的。这里有一个例子:
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
  <sec:filter-chain-map path-type="ant">
     <sec:filter-chain pattern="/webServices/**" filters="
           securityContextPersistenceFilterWithASCFalse,
           basicAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
     <sec:filter-chain pattern="/**" filters="
           securityContextPersistenceFilterWithASCFalse,
           formLoginFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
  </sec:filter-chain-map>
</bean>


你可能注意到FilterSecurityInterceptor声明的不同方式。 命名空间元素filter-chain-map被用来设置安全过滤器链。 它映射一个特定的URL模式,到过滤器链中,从bean名称来定义的filters元素。 它同时支持正则表达式和ant路径,并且只使用第一个出现的匹配URI。 在运行阶段FilterChainProxy会定位当前web请求匹配的第一个URI模式,由filters属性指定的过滤器bean列表将开始处理请求。 过滤器会按照定义的顺序依次执行,所以你可以对处理特定URL的过滤器链进行完全的控制。
你可能注意到了,我们在过滤器链里声明了两个SecurityContextPersistenceFilter(ASC是allowSessionCreation的简写,是SecurityContextPersistenceFilter的一个属性)。 因为web服务从来不会在请求里带上jsessionid,为每个用户代理都创建一个HttpSession完全是一种浪费。 如果你需要构建一个高等级最高可扩展性的系统,我们推荐你使用上面的配置方法。 对于小一点儿的项目,使用一个HttpSessionContextIntegrationFilter(让它的allowSessionCreation默认为true)就足够了。
在有关声明周期的问题上,如果这些方法被FilterChainProxy自己调用,FilterChainProxy会始终根据下一层的Filter代理init(FilterConfig)和destroy()方法。 这时,FilterChainProxy会保证初始化和销毁操作只会在Filter上调用一次, 而不管它在过滤器链中被声明了多少次)。你控制着所有的抉择,比如这些方法是否被调用 或targetFilterLifecycle初始化参数DelegatingFilterProxy。 默认情况下,这个参数是false,servlet容器生命周期调用不会传播到 DelegatingFilterProxy。
当我们了解如何使用命名控制配置构建web安全。 我们使用一个DelegatingFilterProxy,它的名字是“springSecurityFilterChain”。 你应该现在可以看到FilterChainProxy的名字,它是由命名空间创建的。
7.2.1. 绕过过滤器链
通过命名空间,你可以使用filters = "none",来提供一个过滤器bean列表。 这会朝向请求模式,使用安全过滤器链整体。注意任何匹配这个模式的路径不会有任何授权或校验的服务 起作用,它们是可以自由访问的。
7.3. 过滤器顺序[/b]
定义在web.xml里的过滤器的顺序是非常重要的。 不论你实际使用的是哪个过滤器,<filter-mapping>的顺序应该像下面这样:
ChannelProcessingFilter,因为它可能需要重定向到其他协议。
ConcurrentSessionFilter,因为它不使用SecurityContextHolder功能,但是需要更新 SessionRegistry 来从主体中放映正在进行的请求。
SecurityContextPersistenceFilter,这样 SecurityContext可以在web请求的开始阶段通过 SecurityContextHolder建立,然后 SecurityContext的任何修改都会在web请求结束的时候(为下一个web请求做准备)复制到 HttpSession中。
验证执行机制 - UsernamePasswordAuthenticationFilter, CasAuthenticationFilter, BasicAuthenticationFilter 等等 - 这样 SecurityContextHolder 可以被修改,并包含一个合法的 Authentication 请求标志。
SecurityContextHolderAwareRequestFilter,如果,你使用它,把一个Spring Security提醒HttpServletRequestWrapper安装到你的servlet容器里。
RememberMeAuthenticationFilter,这样如果之前的验证执行机制没有更新 SecurityContextHolder,这个请求提供了一个可以使用的remember-me服务的cookie,一个对应的已保存的 Authentication对象会被创建出来。
AnonymousAuthenticationFilter,这样如果之前的验证执行机制没有更新 SecurityContextHolder,会创建一个匿名 Authentication对象。
ExceptionTranslationFilter,用来捕捉 Spring Security异常,这样,可能返回一个HTTP错误响应,或者执行一个对应的 AuthenticationEntryPoint。
FilterSecurityInterceptor,保护web URI。
7.4. 使用其他过滤器 —— 基于框架
如果你在使用SiteMesh,确认Spring Security过滤器在SiteMesh过滤器之前调用。 这可以保证SecurityContextHolder为每个SiteMesh渲染器及时创建。
分享到:
评论

相关推荐

    全面解析Spring Security 过滤器链的机制和特性

    Spring Security 过滤器链是 Spring Security 框架中的一种核心机制,负责处理 HTTP 请求的安全验证和授权。今天,我们将深入探讨 Spring Security 过滤器链的机制和特性,以帮助读者更好地理解和应用 Spring ...

    servlet过滤器实例经典过滤器

    通过实例化和配置过滤器,我们可以实现诸如字符集转换、权限控制、日志记录等多种功能,提升应用的安全性和性能。在学习和使用过程中,一定要深入理解Filter接口的方法和生命周期,以及如何在web.xml中正确配置过滤...

    过滤器文档过滤器使用中的方法过滤器.pdf

    2. **执行过滤**:每当有请求到达时,过滤器链会按注册的顺序依次调用每个过滤器的`doFilter()`方法。在这个方法中,我们可以决定是否允许请求继续到下一个过滤器或Servlet。 3. **销毁**:服务器关闭时,每个过滤器...

    java过滤器例子

    返回时,响应也会按照相反的顺序通过过滤器链。 ### 过滤器的生命周期 1. **初始化(Init)**:当应用启动时,每个过滤器的`init()`方法会被调用一次,用于执行一次性设置,例如加载配置信息。 2. **过滤...

    JAVAEE过滤器的使用

    - 在`web.xml`中配置过滤器,指定过滤器类、URL模式以及过滤器链。 ```xml &lt;filter-name&gt;MyFilter &lt;filter-class&gt;com.example.MyFilterClass&lt;/filter-class&gt; &lt;filter-name&gt;MyFilter &lt;url-pattern&gt;/some...

    设计模式-拦截过滤器

    拦截过滤器模式(Interceptor Filter Pattern)基于责任链模式,通过创建一个过滤器链,每个过滤器都实现一个共同的接口,这个接口定义了对请求进行处理的方法。当请求到达时,它会依次通过这个过滤器链,每个过滤器...

    servlet高级应用过滤器、防盗链等一系列技术工具打包

    本资源包“servlet高级应用过滤器、防盗链等一系列技术工具打包”聚焦于Servlet的高级应用场景,提供了多种实用的技术工具,以提升Web应用程序的安全性、性能和用户体验。 首先,我们来探讨“过滤器(Filter)”。...

    Acegi配置指南[整理].pdf

    `FilterChainProxy` 是 Acegi 中用于定义安全过滤器链的类。`filterInvocationDefinitionSource` 属性配置了过滤器链的规则,如 `/**=httpSessionContextIntegrationFilter, basicProcessionFilter, ...

    过滤器.zip

    1. **过滤器链**:在Web应用中,多个过滤器可以组成一个过滤器链。每个请求会按照在web.xml中声明的顺序,依次通过这些过滤器。每个过滤器都有机会修改请求和响应,或者决定是否继续传递给下一个过滤器。 2. **配置...

    Acegi配置指南

    这确保了Acegi的安全过滤器链能够正确地参与到Web应用的生命周期中。 然后,在Spring的配置文件(如`acegi.xml`)中,需要定义`filterChainProxy` Bean,它定义了过滤器链的顺序和职责: ```xml PATTERN_...

    accp java过滤器 PPT

    过滤器链的概念使得多个过滤器可以按照一定的顺序串联起来,每个过滤器都有机会处理请求和响应。 以下是Java过滤器的一些核心知识点: 1. **Filter接口**:`javax.servlet.Filter`接口定义了三个方法,分别是`init...

    JAVA Web中过滤器

    多个过滤器可以组成一个过滤器链,它们按照在web.xml中的配置顺序依次执行。如果一个请求匹配多个过滤器,那么这些过滤器会按照声明的顺序依次执行doFilter()方法。 6. **常见应用场景** - **字符编码转换**:...

    过滤器进行登录操作

    1. **过滤器链**:多个过滤器可以组成一个过滤器链,每个过滤器按照在web.xml中的声明顺序依次执行。我们可以设置多个过滤器来处理不同的登录需求,比如身份验证、权限检查等。 2. **身份验证**:在用户尝试访问受...

    拦截过滤器模式

    这种模式通过定义一个过滤器链(Filter Chain)来管理一系列过滤器,并将请求传递给实际的目标组件。 #### 二、关键概念与组成 拦截过滤器模式由以下几个核心组成部分构成: 1. **过滤器(Filter)**:这是模式中...

    servlet过滤器技术实例,

    过滤器链的概念使得多个过滤器可以按顺序执行,每个过滤器都可以决定是否将请求传递给下一个过滤器或直接终止。 二、Filter生命周期 每个Servlet过滤器都具有三个关键方法: 1. `init(FilterConfig config)`: 过滤...

    JAVA过滤器标准代码

    - `Test`过滤器则检查用户名是否与配置参数`s`相等,如果相等则重定向到错误页面,否则继续执行请求链中的下一个组件或资源。 3. **销毁方法`destroy()`**: - 当Web容器停止或重新加载应用时,会调用`destroy()`...

    过滤器的编写

    在一个Web应用中,可以有多个过滤器,它们会形成一个过滤器链。当请求到达时,每个过滤器按照配置的顺序依次执行其`doFilter()` 方法。过滤器之间是串行的,一个过滤器处理完后再传递给下一个。 5. **常见应用** ...

    过滤器(Filter)

    完成后,响应会通过过滤器链返回给客户端,过程中同样可以进行相应的后处理。 创建一个过滤器需要继承`javax.servlet.Filter`接口,并实现其核心方法`doFilter()`。以下是一个简单的过滤器示例: ```java public ...

    过滤器拦截并处理request请求

    在实际应用中,过滤器可以串联起来形成一个过滤链。每个过滤器都按照在`web.xml`中的顺序依次执行`doFilter()`方法,直到请求到达目标Servlet。如果一个过滤器选择不转发请求,可以通过不调用`Chain.doFilter()`来...

    servlet+jsp实现过滤器 防止用户未登录访问

    filterChain.doFilter(request, response)是过滤器链中的下一个过滤器,如果存在,或者最终目标页面的处理。如果这个方法不被调用,那么请求就不会传递到目标页面,也就不会渲染任何内容。 此外,destroy方法用于在...

Global site tag (gtag.js) - Google Analytics