Spring Security总体流程、认证流程、鉴权流程浅析

软硬件环境

  • 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

  • 16
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个基于Spring框架的安全框架,它提供了一套完整的安全认证和授机制。下面是Spring Security认证流程: 1. 用户访问需要认证的资源,Spring Security会拦截请求并重定向到登录页面。 2. 用户输入用户名和密码,提交表单。 3. Spring Security会将表单提交的用户名和密码封装成一个Authentication对象。 4. AuthenticationManager接口会根据Authentication对象中的用户名和密码去调用UserDetailsService接口的实现类获取用户信息。 5. 如果获取到用户信息,则将用户信息封装成一个包含限信息的Authentication对象返回给AuthenticationManager。 6. AuthenticationManager会将Authentication对象交给AuthenticationProvider接口的实现类进行认证。 7. 如果认证成功,则将认证成功的Authentication对象返回给Spring Security。 8. Spring Security会将认证成功的Authentication对象存储到SecurityContextHolder中,供后续的访问授使用。 下面是一个简单的Spring Security认证流程的代码示例: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("ADMIN", "USER") .anyRequest().authenticated() .and() .formLogin() .and() .logout().logoutSuccessUrl("/login").permitAll(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值