0%

spring security 过滤器链

过滤器链介绍

spring security采用的是责任链的设计模式,它有一条很长的过滤器链。

客户端向服务端发送请求,然后应用根据请求的 URI 的路径来确定该请求的过滤器链(Filter)以及最终的具体 Servlet 控制器(Controller

从上图我们可以看出 Spring Security 以一个单 Filter(FilterChainProxy) 存在于整个过滤器链中,而这个 FilterChainProxy 实际内部代理着众多的 Spring Security Filter(过滤器链) ,过滤器链的每个元素都是一组URL对应一组过滤器

过滤器链形成

首先 众多的Filter 按照一定的顺序被 SecurityBuilder 的实现来组装为 SecurityFilterChain ,然后通过 WebSecurity 注入到 FilterChainProxy 中去,接着 FilterChainProxy 又在 WebSecurityConfiguration 中以 springSecurityFilterChain 的名称注册为 Spring Bean 。实际上还有一个隐藏层 DelegatingFilterProxy 代理了 springSecurityFilterChain 注入到最后整个 Servlet 过滤器链中,如下图

Spring Security 允许有多条过滤器链并行,Spring SecurityFilterChainProxy 可以代理多条过滤器链并根据不同的 URI 匹配策略进行分发。但是每个请求每次只能被分发到一条过滤器链,实际每条过滤链就是一个 SecurityFilterChain。如下图所示:

过滤器链中的过滤器

过滤器说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(1) WebAsyncManagerIntegrationFilter:将 Security 上下文与 Spring Web 中用于处理异步请求映射的 WebAsyncManager 进行集成。

(2) SecurityContextPersistenceFilter:在每次请求处理之前将该请求相关的安全上下文信息加载到SecurityContextHolder 中,然后在该次请求处理完成之后,将SecurityContextHolder 中关于这次请求的信息存储到一个“仓储”中,然后将SecurityContextHolder 中的信息清除,例如在 Session 中维护一个用户的安全信息就是这个过滤器处理的。

(3) HeaderWriterFilter:用于将头信息加入响应中。

(4) CsrfFilter:用于处理跨站请求伪造。

(5)LogoutFilter:用于处理退出登录。

(6)UsernamePasswordAuthenticationFilter:用于处理基于表单的登录请求,从表单中获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的 usernameParameter 和 passwordParameter 两个参数的值进行修改。

(7)DefaultLoginPageGeneratingFilter:如果没有配置登录页面,那系统初始化时就会配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面。

(8)BasicAuthenticationFilter:检测和处理 http basic 认证。

(9)RequestCacheAwareFilter:用来处理请求的缓存。

(10)SecurityContextHolderAwareRequestFilter:主要是包装请求对象 request。

(11)AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在Authentication 对象,如果不存在为其提供一个匿名 Authentication。

(12)SessionManagementFilter:管理 session 的过滤器

(13)ExceptionTranslationFilter:处理 AccessDeniedException 和AuthenticationException 异常。

(14)FilterSecurityInterceptor:可以看做过滤器链的出口。

(15)RememberMeAuthenticationFilter:当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的 remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启。