这篇文章主要介绍“spring security中AuthenticationManagerBuilder怎么理解”,在日常操作中,相信很多人在spring security中AuthenticationManagerBuilder怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”spring security中AuthenticationManagerBuilder怎么理解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!在 Spring Security 中,用来处理身份认证的类是 AuthenticationManager,我们也称之为认证管理器。AuthenticationManager 中规范了 Spring Security 的过滤器要如何执行身份认证,并在身份认证成功后返回一个经过认证的 Authentication 对象。AuthenticationManager 是一个接口,我们可以自定义它的实现,但是通常我们使用更多的是系统提供的 ProviderManager。ProviderManager 是的最常用的 AuthenticationManager 实现类。ProviderManager 管理了一个 AuthenticationProvider 列表,每个 AuthenticationProvider 都是一个认证器,不同的 AuthenticationProvider 用来处理不同的 Authentication 对象的认证。一次完整的身份认证流程可能会经过多个 AuthenticationProvider。ProviderManager 相当于代理了多个 AuthenticationProvider,他们的关系如下图:AuthenticationProvider 定义了 Spring Security 中的验证逻辑,我们来看下 AuthenticationProvider 的定义:可以看到,AuthenticationProvider 中就两个方法:在一次完整的认证中,可能包含多个 AuthenticationProvider,而这多个 AuthenticationProvider 则由 ProviderManager 进行统一管理。最常用的 AuthenticationProvider 实现类是 DaoAuthenticationProvider。每一个 ProviderManager 管理多个 AuthenticationProvider,同时每一个 ProviderManager 都可以配置一个 parent,如果当前的 ProviderManager 中认证失败了,还可以去它的 parent 中继续执行认证,所谓的 parent 实例,一般也是 ProviderManager,也就是 ProviderManager 的 parent 还是 ProviderManager。可以参考如下架构图:从上面的分析中大家可以看出,AuthenticationManager 的初始化会分为两块,一个全局的 AuthenticationManager,也就是 parent,另一个则是局部的 AuthenticationManager。先给大家一个结论,一个系统中,我们可以配置多个 HttpSecurity(参见Spring Security 竟然可以同时存在多个过滤器链?),而每一个 HttpSecurity 都有一个对应的 AuthenticationManager 实例(局部 AuthenticationManager),这些局部的 AuthenticationManager 实例都有一个共同的 parent,那就是全局的 AuthenticationManager。接下来,我们通过源码分析来验证我们上面的结论。
在上篇文章中,松哥已经和大家分析了 SecurityBuilder 的几个常见实现类 AbstractSecurityBuilder、AbstractConfiguredSecurityBuilder、HttpSecurityBuilder,本文关于这几个类我就不重复介绍了。我们直接来看 AuthenticationManagerBuilder,先来看它的一个继承关系:可以看到, AuthenticationManagerBuilder 已经自动具备了其父类的功能。AuthenticationManagerBuilder 的源码比较长,我们来看几个关键的方法:
不过自己配置有一个问题就是我们没有配置 ProviderManager 的 parent,没有配置的话,如果当前 ProviderManager 中认证失败的话,就直接抛出失败,而不会去 parent 中再次进行认证了(一般来说也不需要,如果系统比较复杂的话,可能需要)。AuthenticationManagerBuilder 还有一个实现类叫做 DefaultPasswordEncoderAuthenticationManagerBuilder,作为内部类分别定义在 WebSecurityConfigurerAdapter 和 AuthenticationConfiguration 中,不过 DefaultPasswordEncoderAuthenticationManagerBuilder 的内容比较简单,重写了父类 AuthenticationManagerBuilder 的几个方法,配置了新的 PasswordEncoder,无他,所以这里我就不列出这个的源码了,感兴趣的小伙伴可以自行查看。但是这并不是说 DefaultPasswordEncoderAuthenticationManagerBuilder 就不重要了,因为在后面的使用中,基本上都是使用 DefaultPasswordEncoderAuthenticationManagerBuilder 来构建 AuthenticationManagerBuilder。好啦,这就是 AuthenticationManagerBuilder。那么是什么时候通过 AuthenticationManagerBuilder 来构建 AuthenticationManager 的呢?这就涉及到我们的老熟人 WebSecurityConfigurerAdapter 了。今天我们主要来看下如何在 WebSecurityConfigurerAdapter 中开启 AuthenticationManager 的初始化的。在初始化流程中,松哥得先和大家介绍一个 AuthenticationConfiguration 类。这个类大家可以当作是一个全局被配类来理解,里边都是一些全局属性的配置:这就是 AuthenticationConfiguration 的主要功能,它主要是提供了一些全局的 Bean,这些全局的 Bean 虽然一定会初始化,但是并非一定用到。那么到底什么时候用到,什么时候用不到,这就和 WebSecurityConfigurerAdapter 有关了,在 WebSecurityConfigurerAdapter 中有三个重要的方法涉及到 AuthenticationManager 的初始化问题,第一个是 setApplicationContext 方法:在该方法中,创 香港云主机建了两个几乎一摸一样的 AuthenticationManagerBuilder 实例,为什么会有两个呢?第一个 authenticationBuilder 是一个局部的 AuthenticationManagerBuilder,将来会传入 HttpSecurity 中去构建局部的 AuthenticationManager;第二个 localConfigureAuthenticationBldr 则是一个用来构建全局 AuthenticationManager 的 AuthenticationManagerBuilder。有小伙伴会问了,构建全局的 AuthenticationManager 不是一开始就在 AuthenticationConfiguration 中创建了吗?为什么这里还有一个?是的,当前这个 localConfigureAuthenticationBldr 是可以禁用的,如果禁用了,就会使用 AuthenticationConfiguration 中提供的 AuthenticationManagerBuilder,如果没禁用,就使用 localConfigureAuthenticationBldr 来构建全局的 AuthenticationManager。另一个方法则是 getHttp 方法:在 getHttp 方法中,会首先调用 authenticationManager 方法去获取一个全局的 AuthenticationManager,并设置给 authenticationBuilder 作为 parent,然后在构建 HttpSecurity 时将 authenticationBuilder 传入进去。那么接下来就是 authenticationManager() 方法到底是怎么执行的了:可以看到,如果 AuthenticationManager 还没初始化,那就先进行初始化。初始化首先调用 configure 方法,默认情况下,configure 方法里边会把 disableLocalConfigureAuthenticationBldr 变量设置为 true,这样接下来就会进入到 if 分支中了。这个 configure 方法不知道大家有没有觉得眼熟?我们在自定义的 SecurityConfig 配置类中,一般都是要重写该方法的,一旦重写了这个方法,那么 disableLocalConfigureAuthenticationBldr 变量就不会变为 true,依然是 false,这样在获取 authenticationManager 的时候就会进入到 else 分支中。如果进入到 if 分支中,意味着开发者并没有重写 configure 方法,AuthenticationManagerBuilder 就使用默认的,大家可以看到,此时就是调用 authenticationConfiguration.getAuthenticationManager() 方法去获取 AuthenticationManager,也就是一开始我们说的那个全局的配置。如果开发者重写了 configure 方法,意味着开发者对 AuthenticationManagerBuilder 进行了一些定制,此时就不能继续使用 AuthenticationConfiguration 中配置的默认的的 AuthenticationManager 了,而要根据开发者 的具体配置,调用 localConfigureAuthenticationBldr.build 方法去构建新的 AuthenticationManager。一言以蔽之,AuthenticationConfiguration 中的配置有没有用上,全看开发者有没有重写 configure(AuthenticationManagerBuilder auth)
方法,重写了,就用 localConfigureAuthenticationBldr 来构建 parent 级别的 AuthenticationManager,没重写,就用 AuthenticationConfiguration 中的方法来构建。这是扮演 parent 角色的 AuthenticationManager 的构建过程,当然,parent 并非必须,如果你没有这个需求的话,也可以不配置 parent。最后我们再来看下局部的 AuthenticationManager 是如何构建的,也就是和 HttpSecurity 绑定的那个 AuthenticationManager。根据前面的介绍,HttpSecurity 在构建的时候就会传入 AuthenticationManagerBuilder,如下:传入进来的 AuthenticationManagerBuilder ,二话不说就存到 SharedObject 里边去了,这个根据官方的注释,说它是一个在不同 Configurer 中共享的对象的工具,其实你可以理解为一个缓存,现在存进去,需要的时候再取出来。取出来的方法,在 HttpSecurity 中也定义好了,如下:在 HttpSecurity 中,凡是涉及到 AuthenticationManager 配置的,都会调用到 getAuthenticationRegistry 方法,如下:最后在 HttpSecurity 的 beforeConfigure 方法中完成构建:到此,关于“spring security中AuthenticationManagerBuilder怎么理解”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注开发云网站,小编会继续努力为大家带来更多实用的文章!
这篇文章给大家介绍http状态码中301和302有什么区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。状态码(Status Code)的职责是当客户端向服务器发送请求时,描述返回的请求结果。 标准状态码由3位数字组成,主要是以下5类:3…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。