软硬件环境:
- jdk1.8
- IntelliJIdea
- SpringBoot2.2.1.RELEASE
- SpringSecurity5.2.1RELEASE
声明: SpringSecurity默认提供的登录方式有表单登录与弹框登录。本文流程图,基于SpringSecurity的表单登录绘制;表单登录与弹框登录流程几乎一致,明白了其中一个的流程,就明白了整个流程了。
Spring Security总体流程分析:
SpringSecurity框架的FilterChainProxy$VirtualFilterChain
类里面,持有着两大过滤器字段
,一是SpringSecurity附加的过滤器List<Filter> additionalFilters
,一是应用本身的过滤器FilterChain originalChain(过滤链里面的过滤器)
。SpringSecurity会先过滤其提供的additionalFilters,然后再过滤应用本身的过滤器
,总体流程如下图所示:
认证流程分析:
认证抽象类AbstractAuthenticationProcessingFilter持有private RequestMatcher requiresAuthenticationRequestMatcher,此匹配器决定
当前AbstractAuthenticationProcessingFilter类(的实现子类)是否对当前请求进行认证
。如果需要认证,那么就进行认证。认证操作,实际是由AuthenticationProvider(接口的实现)完成的
。认证抽象类AbstractAuthenticationProcessingFilter持有AuthenticationManager接口对象,该对象(一般由ProviderManager提供实现),ProviderManager持有AuthenticationProvider对象集合。认证时,就是遍历AuthenticationProvider对象集合,只要有一个AuthenticationProvider认证成功了,那么就认证通过,见下图:
而AuthenticationProvider接口的实现较多,有:
所以,认证流程,总体上是这样的:
注:如果需要认证,但是又认证失败的话,会抛出异常。
注:假设a、b、c都是抽象类AbstractAuthenticationProcessingFilter的子类,如果a、b、c 都能成功匹配同一个url(即:访问该url时,request会依次被a、b、c进行过滤认证),那么一旦a、b、c中有一个认证失败,那么就认证不通过。如果a、b、c都认证成功,那么是认证通过的,不过此时用户的信息数据,是以最后一个认证器存的数据为准的。
-
所以,
如果自定义了多个认证过滤器
(即AbstractAuthenticationProcessingFilter子类)的话,建议每个认证过滤器都匹配不同的url
。 -
【如果a、b、c 都能成功匹配同一个url(即:访问该url时,request会依次被a、b、c 进行过滤认证)】中,【request会依次被a、b、c 进行过滤认证】的前提是:前面的认证过滤器没有做什么“截断”操作(如请求转发,请求重定向等)。
-
Spring Security中,只要某一个认证器认证成功,就会
调用到AbstractAuthenticationTargetUrlRequestHandler类中的handle方法,将请求重定向一个新的URL
(这个URL的具体地址由AbstractAuthenticationTargetUrlRequestHandler类中的handle方法提供)。也就是说,Spring Security默认的,如果多个认证过滤器同时匹配同一个登录URL的话
,如果自己不作特殊处理,只有排在最前的那个认证器生效
。
鉴权流程分析:
鉴权流程相对简单。AbstractSecurityInterceptor抽象类中有一个方法public abstract SecurityMetadataSource obtainSecurityMetadataSource(),其子类需要重写该方法,使其能获得一个SecurityMetadataSource实例
,这个实例用来判定当前请求是否需鉴权
;AbstractSecurityInterceptor抽象类中有一个字段private AccessDecisionManager accessDecisionManager,其子类需要给这个字段赋一个AccessDecisionManager实例
,这个实例用来判定鉴权是否通过(如果需要鉴权的话)
,见下图:
如果有多个鉴权过滤器的话:
Spring Security基础理论梳理完毕 !
^_^ 如有不当之处,欢迎指正
^_^ 参考资料
《SpringSecurity5.2.1RELEASE源码》
^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng