上篇回顾
上篇介绍了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的运行过程》