官网地址 Spring Security Reference
版本:Version 5.5.0
【Spring Security】—— 配置器 SecurityConfigurer 接口三个分支
概述
SpringSecurity 中的配置器在之前的文章中几乎都提到过,它的作用是用来配置构造器的。在开始学习的第一篇文章中就有关于 SecurityConfigurer 的简单介绍:
【【Spring Security】—— WebSecurityConfigurerAdapter】,WebSecurityConfigurerAdapter 也是一个构造器。
在上一篇关于 HttpSecurity 的文章中,有很多方法,都有相同的结构:
- 都调用 getOrApply 方法将特定的配置器应用到构造器(即:HttpSecurity)
- 都立刻返回应用的配置器,便于调用方对配置器进行自定义的配置
本章主要内容是关于配置器的接口架构,任意找一个配置器一直往上找,就会找到配置器的顶级接口:SecurityConfigurer
利用 Idea 工具可以看到它的实现类情况:
在 AbstractHttpConfigurer 抽象类的下面可以看到所有用来配置 HttpSecurity 构造器的配置器实现类。
再通过继承关系图,看看配置器顶层的架构:
SecurityConfigurer 接口
下面是在最开始学习 Spring Security 时看到 SecurityConfigurer 产生的疑问:
解答:当时太异想天开了,SecurityConfigurer 的所有实现类都是用来配置构造器的,也就是说,泛型中 O 和 B 的关系是,B 用来构造 O 而配置器的作用是配置这个构造器的,从而影响最终构造的的结果。如果设计成一个配置器同时配置多个构造器,那么构造器就要改成一次构造出多个对象,这样及复杂,又没有意义。
接下来就是从 SecurityConfigurer 这个顶级接口出来的三个分支:
SecurityConfigurerAdapter
源码注释:SecurityConfigurer 的基础实现类,它允许子类只实现他们感兴趣的方法。它还提供了一种机制,用于使用 SecurityConfigurer 并在完成后获得对正在配置的 SecurityBuilder 的访问权限。
接下了就来看看源码是怎么实现注释中所说的功能的
首先还是看看 SecurityConfigurerAdapter 中都有什么:
内容很简单:
-
有一个内部类 CompositeObjectPostProcessor
复合后置处理器对象类 -
定义了两个成员变量:
将要配置的 securityBuilder 构造器
复合后置处理器 objectPostProcessor -
从接口中实现的方法和自己新加的几个方法
init 和 configure 是实现接口的方法
and、getBuilder、postProcess、addObjectPostProcessor、setBuilder 方法是自己加的
它允许子类只实现他们感兴趣的方法
在源码中可以看到,所有的方法都有方法体,包括对接口方法的实现(虽然是空方法体)。所以继承 SecurityConfigurerAdapter 的配置器可以根据自己的需求实现(覆盖)自己感兴趣的方法。(即,可以自己实现 init ,但是如果自己不需要初始化,也可以不实现,在构造器调用其 init 方法时什么也不做)。
使用 SecurityConfigurer 完成后获得对正在配置的 SecurityBuilder 的访问权限的机制
/**
* Return the SecurityBuilder when done using the SecurityConfigurer.
*/
public B and() {
return getBuilder();
}
/**
* Gets the SecurityBuilder. Cannot be null.
*/
protected final B getBuilder() {
if (securityBuilder == null) {
throw new IllegalStateException("securityBuilder cannot be null");
}
return securityBuilder;
}
这里是实现这种机制的源码,and 方法在使用完配置器之后调用,获得正在配置的 SecurityBuilder 对象。
有必要说一下为什么是正在配置的,因为在这个时候还没有对构造器进行配置。配置构造器的时机在调用构造器的 build 方法时,在前面的文章中讲到过构造对象的过程,doBuild方法中加入了构建生命周期的控制,在里面才开始调用各个配置器的 init 方法和 configure 方法。所以这里获取到的时正在配置的 SecurityBuilder 对象。这也体现了对象的职责界限很清晰,构建又构建器完成,在构建的过程中构建器利用配置器进行配置。
setBuilder 方法
这个方法有点特别,所以单独说一下,方法内容很简单,就是设置构造器成员变量的,但是官网又这样一句注释:
Sets the SecurityBuilder to be used. This is automatically set when using AbstractConfiguredSecurityBuilder.apply(SecurityConfigurerAdapter)
第一句很好理解:这个方法是来设置将要配置的构造器的
第二句就要结合 AbstractConfiguredSecurityBuilder 了(这样就穿起来了):
(回顾连接:构建者)
这是 AbstractConfiguredSecurityBuilder 中对应的源码,这一块儿在之前的文章中也讲到过可以点击上面的连接回顾。看到这里有了新的体会:
这样看来,构造器再被应用之前是不知道要配置哪个构造器的。在构造器调用 apply 方法时才真正设置配置器的 securityBuilder 变量。所以官方注释才说 setBuilder 方法时自动调用的,我们不能手动去设置。
只有构造器应用了这个配置器,这个配置器才会绑定上这个构造器。这样构造器就很灵活了。感叹!!!
复合后置处理对象
这个内部类对象很简单,看一下内部类的内容就明白了:它维护的是一个 List 集合
private List<ObjectPostProcessor<?>> postProcessors = new ArrayList<>();
因此称之为:复合后置处理对象(CompositeObjectPostProcessor),就是里面有多个。
GlobalAuthenticationConfigurerAdapter
这个类的类名说明它是一个全局配置相关的类。
@Order(100)
public abstract class GlobalAuthenticationConfigurerAdapter implements
SecurityConfigurer<AuthenticationManager, AuthenticationManagerBuilder> {
public void init(AuthenticationManagerBuilder auth) throws Exception {
}
public void configure(AuthenticationManagerBuilder auth) throws Exception {
}
}
从源码可以看出它实现 SecurityConfigurer 接口,没有具体的实现内容,只是对构造器和构造器将要构造的对象做了限制:
- 将要配置的构造器:AuthenticationManagerBuilder
- 将要构建的对象:AuthenticationManager
官网注释:可以作为 bean 公开以配置全局 AuthenticationManagerBuilder 的 SecurityConfigurer。 AuthenticationConfiguration 自动使用这种类型的 Bean 来配置全局 AuthenticationManagerBuilder。
从官网的注释可以看出, GlobalAuthenticationConfigurerAdapter 的实现类和配置 AuthenticationManager 有关。可以看出 AuthenticationManagerBuilder 和 AuthenticationManager 应该有全局和局部之分,具体的细节将来碰到了再细看。
WebSecurityConfigurer
这个在之前的文章中有介绍,不做赘述了,贴了部分内容的截图: 详细可参考【Spring Security】—— WebSecurityConfigurerAdapter
总结
SecurityConfigurer 是构造器的顶级接口,下面主要有三个分支
-
SecurityConfigurerAdapter
允许子类只实现他们感兴趣的方法。
and 方法可以再使用完配置器后返回正在配置的构造器。
setBuilder 方法是由构造器 apply 方法中自动调用的。
有个复合后置处理器内部类,维护一个 List 集合,可存储多个后置处理器对象 -
GlobalAuthenticationConfigurerAdapter
可以作为 bean 公开以配置全局 AuthenticationManagerBuilder 的 SecurityConfigurer。 AuthenticationConfiguration 自动使用这种类型的 Bean 来配置全局 AuthenticationManagerBuilder。
一句话:配置全局 AuthenticationManagerBuilder 的
-
WebSecurityConfigurer
唯一抽象实现类:WebSecurityConfigurerAdapterWebSecurityConfigurerAdapter 为创建 WebSecurityConfigurer 实例提供方便的基类。 该实现允许通过覆盖方法进行定制。