在一个使用了Spring Security 的 Web 应用中,安全目标的达成基于 Servlet
规范的Filter
机制 :
- 客户端对应用发起请求,容器基于请求
URI
决定应用哪个servlet
和哪些filters
; - 每个请求最多由某一个
servlet
处理 ; - 所有要应用的
filter
按照特定顺序形成一个链;Filter
顺序的决定Filter
bean定义通过使用注解@Order
或者实现接口Ordered
;FilterRegistrationBean
API 本身有顺序属性;
- 链中的某个
filter
如果想自己处理请求,甚至可以否决链的其他部分; - 某个
filter
可以修改请求/响应对象;
从Web
容器角度,整个Spring Security
安全机制是封装为一个Filter
存在的,而不是多个Filter
- 该安全
filter
的实现类为FilterChainProxy
; - 该安全
filter
是一个以bean
的形式缺省被安装; - 从
Web
容器角度看,FilterChainProxy
是一个filter
,但其内部是一个filter chain
,有多个filter
; - 实际上在
FilterChainProxy
之上还有一层DelegatingFilterProxy
DelegatingFilterProxy
不一定是一个bean
,FilterChainProxy
总是一个bean
;DelegatingFilterProxy
把实际工作交给FilterChainProxy
来做;
FilterChainProxy
的名字总是叫做springSecurityFilterChain
;FilterChainProxy
包含了所有的安全逻辑,内部组织为一个filter chain
;- 所有这些内部的安全
filter
也都实现了Servlet规范
中标准的Filter
接口;
- 所有这些内部的安全
FilterChainProxy
可以管理多个filter chain
,这些对容器是透明的;FilterChainProxy
发请求派发给第一个匹配的filter chain
来处理;
一个使用了Spring Security
的Spring Boot Web
应用,其FilterChainProxy filter
中通常会有包含若干个filter chain
,这里我们假定有n
个 :
- 前
n-1
个filter chain
通常用来忽略静态资源,比如分别对应/css/**
,/images/**
,error view/error
等; - 最后一个用来匹配
/**
,其中包含了认证,授权,异常处理,会话处理,头部写入等等主要安全逻辑。- 缺省情况下这个
filter chain
包含多个filter
,一般情况下用户不需要关注它们是什么,什么时候用。
- 缺省情况下这个
Spring Boot Web
应用中,FilterChainProxy bean
由安全配置类WebSecurityConfiguration
创建 :
- 整个应用对应一个
WebSecurity
实例,代表整个应用所有的Web
安全配置; WebSecurity
实例 对应多个WebSecurityConfigurer
实例 ;- 每个
WebSecurityConfigurer
实例对应一个HttpSecurity
实例;
- 每个
WebSecurityConfiguration
使用上面的WebSecurity
创建bean FilterChainProxy springSecurityFilterChain
;WebSecurity::build()
创建并返回了类型为FilterChainProxy
对象;- 每个
WebSecurityConfigurer
实例对应生成FilterChainProxy
中的一个filter chain
; - 每个
web.ignoring().antMatchers()
调用对应生成FilterChainProxy
中的一个filter chain
;