上篇回顾
上篇介绍了HttpSecurity
如何建造过滤器链,本文主要介绍几个主要的过滤器。
认证过滤器 UsernamePasswordAuthenticationFilter
参数有username
,password
的,走UsernamePasswordAuthenticationFilter
,提取参数构造UsernamePasswordAuthenticationToken
进行认证,成功则填充SecurityContextHolder的Authentication
UsernamePasswordAuthenticationFilter
实现了其父类AbstractAuthenticationProcessingFilter
中的attemptAuthentication
方法。这个方法会调用认证管理器AuthenticationManager
去认证。
AbstractAuthenticationProcessingFilter
中的doFilter()
方法,会判断每个请求是否需要认证。
不需要认证的请求直接放行,需要的认证的会被拦下。
判断是否需要认证是怎么做的呢?
其实是我们在调用httpSecurity.formLogin().permitAll()
时设置的。
ProviderManager
是认证管理器AuthenticationManager
的默认实现
通过提供不同的AuthenticationProvider
实现类,可以通过多种方式进行认证
其内部会调用authenticate(Authentication authentication)
遍历providers,调用provider.authenticate()
来尝试认证
我们可以实现AuthenticationProvider
接口,重写authenticate()
方法,来查询数据库对用户名密码做认证
PS: 上面的
parent
其实就是存放的我们自定义编写的provider的认证管理器。这里就不贴出来了
认证过滤器 BasicAuthenticationFilter
header里头有Authorization
,而且value是以Basic
开头的,则走BasicAuthenticationFilter
,提取参数构造UsernamePasswordAuthenticationToken
进行认证,成功则填充SecurityContextHolder的Authentication
认证过滤器 AnonymousAuthenticationFilter
给没有登陆的用户,填充AnonymousAuthenticationToken
到SecurityContextHolder
的Authentication
授权过滤器 AbstractSecurityInterceptor
默认的过滤器是
FilterSecurityInterceptor
,继承了AbstractSecurityInterceptor
实现了Filter
接口
我们一般直接继承这个过滤器或者继承他的父类,自定义一个AuthorizeSecurityInterceptor
。
目的是为了注入自定义的授权管理器AccessDecisionManager
、和权限元数据FilterInvocationSecurityMetadataSource
FilterSecurityInterceptor
是在WebSecurityConfigurerAdapter
的init()
里配置的
FilterSecurityInterceptor
中的doFilter()
会调用super.beforeInvocation(fi)
方法,内部调用授权管理器做授权
自定义的
AuthorizeSecurityMetadataSource
实现了FilterInvocationSecurityMetadataSource
的getAttributes()
方法,可以根据url获取对应的角色列表
自定义的
AuthorizeAccessDecisionManager
实现了AccessDecisionManager
,实现了decide()
方法来判断当前用户是否有此url的权限
框架默认的
AccessDecisionManager
通过投票决策的方式来授权
-
AffirmativeBased
(spring security默认使用)只要有投通过(
ACCESS_GRANTED=1
)票,则直接判为通过。如果没有投通过票且反对(ACCESS_DENIED=-1
)票在1个及其以上的,则直接判为不通过。 -
ConsensusBased
(少数服从多数)通过的票数大于反对的票数则判为通过;通过的票数小于反对的票数则判为不通过;通过的票数和反对的票数相等,则可根据配置allowIfEqualGrantedDeniedDecisions(默认为true)进行判断是否通过。
-
UnanimousBased
(反对票优先)无论多少投票者投了多少通过(ACCESS_GRANTED)票,只要有反对票(ACCESS_DENIED),那都判为不通过;如果没有反对票且有投票者投了通过票,那么就判为通过.
其他过滤器
ExceptionTranslationFilter
:
该过滤器主要用来捕获处理spring security抛出的异常,异常主要来源于FilterSecurityInterceptor
系列文章:《深入浅出Spring Security(一):三句话解释框架原理》
系列文章:《深入浅出Spring Security(二):FilterChainProxy的创建过程》
系列文章:《深入浅出Spring Security(三):FilterChainProxy的运行过程》