专栏名称: 码农小胖哥
技术公众号:码农小胖哥
51好读  ›  专栏  ›  码农小胖哥

Spring Security 实战干货:AuthenticationManager的初始化细节

码农小胖哥  · 掘金  ·  · 2021-01-25 07:42

正文

阅读 286

Spring Security 实战干货:AuthenticationManager的初始化细节

投票传送门

1. 前言

今天有个同学告诉我,在 Security Learning 项目的 day11 分支中出现了一个问题,验证码登录和其它登录不兼容了,出现了 No Provider 异常。还有这事?我赶紧跑了一遍还真是,看来我大意了,不过最终找到了原因,问题就出在 AuthenticationManager 的初始化上。自定义了一个 UseDetailService AuthenticationProvider 之后 AuthenticationManager 的默认初始化出问题了。

虽然在 Spring Security 实战干货:图解认证管理器AuthenticationManager 一文中对 AuthenticationManager 的流程进行了分析,但是还是不够深入,以至于出现了问题。今天就把这个坑补了。

2. AuthenticationManager的初始化

关于 AuthenticationManager 的初始化,流程部分请看这一篇 文章 ,里面有流程图。在流程图中我们提到了 AuthenticationManager 的默认初始化是由 AuthenticationConfiguration 完成的,但是只是一笔带过,具体的细节没有搞清楚。现在就搞定它。

AuthenticationConfiguration

AuthenticationConfiguration 初始化 AuthenticationManager 的核心方法就是下面这个方法:

public AuthenticationManager getAuthenticationManager() throws Exception {
    // 先判断 AuthenticationManager 是否初始化
   if (this.authenticationManagerInitialized) {
       // 如果已经初始化 那么直接返回初始化的
      return this.authenticationManager;
   }
    // 否则就去 Spring IoC 中获取其构建类
   AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean(AuthenticationManagerBuilder.class);
    // 如果不是第一次构建  好像是每次总要通过Builder来进行构建
   if (this.buildingAuthenticationManager.getAndSet(true)) {
       // 返回 一个委托的AuthenticationManager
      return new AuthenticationManagerDelegator(authBuilder);
   }
   // 如果是第一次通过Builder构建 将全局的认证配置整合到Builder中  那么以后就不用再整合全局的配置了
   for (GlobalAuthenticationConfigurerAdapter config : globalAuthConfigurers) {
      authBuilder.apply(config);
   }
   // 构建AuthenticationManager 
   authenticationManager = authBuilder.build();
   // 如果构建结果为null 
   if (authenticationManager == null) {
       // 再次尝试去Spring IoC 获取懒加载的 AuthenticationManager  Bean
      authenticationManager = getAuthenticationManagerBean();
   }
   // 修改初始化状态 
   this.authenticationManagerInitialized = true;
   return authenticationManager;
}
复制代码






请到「今天看啥」查看全文