【Spring Security】—— 配置器 SecurityConfigurer 接口三个分支

官网地址 Spring Security Reference

版本:Version 5.5.0

概述

SpringSecurity 中的配置器在之前的文章中几乎都提到过,它的作用是用来配置构造器的。在开始学习的第一篇文章中就有关于 SecurityConfigurer 的简单介绍:
【【Spring Security】—— WebSecurityConfigurerAdapter】,WebSecurityConfigurerAdapter 也是一个构造器。

在上一篇关于 HttpSecurity 的文章中,有很多方法,都有相同的结构:

  • 都调用 getOrApply 方法将特定的配置器应用到构造器(即:HttpSecurity)
  • 都立刻返回应用的配置器,便于调用方对配置器进行自定义的配置

本章主要内容是关于配置器的接口架构,任意找一个配置器一直往上找,就会找到配置器的顶级接口:SecurityConfigurer

利用 Idea 工具可以看到它的实现类情况:
在这里插入图片描述

在 AbstractHttpConfigurer 抽象类的下面可以看到所有用来配置 HttpSecurity 构造器的配置器实现类。

再通过继承关系图,看看配置器顶层的架构:
在这里插入图片描述

SecurityConfigurer 接口

详细可 参考【Spring Security】—— WebSecurityConfigurerAdapter

下面是在最开始学习 Spring Security 时看到 SecurityConfigurer 产生的疑问:
在这里插入图片描述
解答:当时太异想天开了,SecurityConfigurer 的所有实现类都是用来配置构造器的,也就是说,泛型中 O 和 B 的关系是,B 用来构造 O 而配置器的作用是配置这个构造器的,从而影响最终构造的的结果。如果设计成一个配置器同时配置多个构造器,那么构造器就要改成一次构造出多个对象,这样及复杂,又没有意义。

接下来就是从 SecurityConfigurer 这个顶级接口出来的三个分支:

SecurityConfigurerAdapter

源码注释:SecurityConfigurer 的基础实现类,它允许子类只实现他们感兴趣的方法。它还提供了一种机制,用于使用 SecurityConfigurer 并在完成后获得对正在配置的 SecurityBuilder 的访问权限。

接下了就来看看源码是怎么实现注释中所说的功能的

首先还是看看 SecurityConfigurerAdapter 中都有什么:
在这里插入图片描述
内容很简单:

  1. 有一个内部类 CompositeObjectPostProcessor
    复合后置处理器对象类

  2. 定义了两个成员变量:
    将要配置的 securityBuilder 构造器
    复合后置处理器 objectPostProcessor

  3. 从接口中实现的方法和自己新加的几个方法
    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 是构造器的顶级接口,下面主要有三个分支

  1. SecurityConfigurerAdapter
    允许子类只实现他们感兴趣的方法。
    and 方法可以再使用完配置器后返回正在配置的构造器。
    setBuilder 方法是由构造器 apply 方法中自动调用的。
    有个复合后置处理器内部类,维护一个 List 集合,可存储多个后置处理器对象

  2. GlobalAuthenticationConfigurerAdapter

    可以作为 bean 公开以配置全局 AuthenticationManagerBuilder 的 SecurityConfigurer。 AuthenticationConfiguration 自动使用这种类型的 Bean 来配置全局 AuthenticationManagerBuilder。

    一句话:配置全局 AuthenticationManagerBuilder 的

  3. WebSecurityConfigurer
    唯一抽象实现类:WebSecurityConfigurerAdapter

    WebSecurityConfigurerAdapter 为创建 WebSecurityConfigurer 实例提供方便的基类。 该实现允许通过覆盖方法进行定制。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值