浅析Spring Security过滤流程
前言
记录对Spring Security过滤流程的梳理结果
总览
当用户端发送请求到我们的Web应用时,首先是Container
(例如Tomcat)接收到请求,然后通过一系列的Filter
后到达具体的Servlet
Filter
顺序在Spring Boot中有两种控制机制
-
Filter
类型的Bean
使用@Order
注解或实现Ordered
接口 - 使用
FilterRegistrationBean
为其设置顺序
Spring Security在其中的角色就是众多Filter
中的一个,其具体类型为 FilterChainProxy
,顾名思义,它内部处理流程其实也是 FilterChain
实际上,被直接安装到Container
中的Filter
其实是DelegatingFilterProxy
,它本身不实现任何逻辑,仅仅是FilterChainProxy
的代理
FilterChainProxy
内部拥有多条SecurityFilterChain
,它会根据Url
选择最匹配的FilterChain
进行处理
SecurityFilterChain
安全一般包含两个问题:
-
Authentication
:你是谁 -
Authorization
:你能做什么
所以每条SecurityFilterChain
都要解决这两个问题
Authentication
AuthenticationManager
是Spring Security中身份认证策略的主要接口
它只有一个方法authenticate
:
- 认证通过则返回
Authentication
对象 - 认证失败则抛出
AuthenticationException
- 无法判断则返回
null
而ProviderManager
则是最常用的实现类,它内部其实是一条AuthenticationProvider
组成的处理链
AuthenticationProvider
与AuthenticationManager
类似,但它多一个方法:
authenticate
-
supports
(供调用者判断其是否能处理相关类型认证)
通常对于系统内的不同资源我们会有不同的认证策略(不同的SecurityFilterChain
),每一种策略都有各自的AuthenticationManager
进行管理。我们在配置AuthenticationManager
时一般只是配置从哪里获取用户信息
,其内部的处理链会使用这些信息进行认证
ProviderManger
进行认证时会遍历处理链,找到能处理该类型认证的AuthenticationProvider
并让其处理,如果没有找到相应的AuthenticationProvider
或其处理结果为null
,则向可能存在的parent
(Global ProviderManager)发出处理请求
Authorization
AccessDecisionManager
是权限认证策略的主要接口,包含三个方法:
-
decide
: 判断是否授权,void 方法,拒绝时抛出AccessDeniedException
-
supports
: 有两个重载方法,判断是否支持该类型权限的裁决
授权对通过认证后的Authentication
进行裁决, AffirmativeBased
是最常用的实现类,内部是由AccessDecisionVoter
组成的处理链,与ProviderManager
类似,不过它没有Parent
AffirmativeBased
进行认证时直接遍历内部处理链直到某个AccessDecisionVoter
返回确认或拒绝授权则处理结束。所有AccessDecisionVoter
都弃权时则根据allowIfAllAbstainDecisions
属性决定
Filter
SecurityFilterChain
内部是javax.servlet.Filter
组成的处理链,常见的如:
-
BasicAuthenticationFilter
: 用户名密码验证 -
BearerTokenAuthenticationFilter
: 基于token验证
Filter
就是实现各种逻辑的主要地方,我们根据业务写的Filter
也主要放在这里,Security自带的过滤器多会与AuthenticationManager
互动
FilterSecurityInterceptor
每条SecurityFilterChain
(默认或自定义)最后一个Filter
必定是FilterSecurityInterceptor
在Spring Security中它决定Request
最终能否通过过滤,主要行为是将通过前面所有Filter
后AuthenticationManager
产生的Authentication
交由AccessDecisionManager
处理,通过授权则通过过滤