Java最新深入理解 SecurityConfigurer 【源码篇】,Dubbo SPI及自适应扩展原理

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

init 就是一个初始化方法。而 configure 则是一个配置方法。这里只是规范了方法的定义,具体的实现则在不同的实现类中。

需要注意的是这两个方法的参数类型都是一个泛型 B,也就是 SecurityBuilder 的子类,关于 SecurityBuilder ,它是用来构建过滤器链的,松哥将在下篇文章中和大家介绍。

SecurityConfigurer 有三个实现类:

  • SecurityConfigurerAdapter

  • GlobalAuthenticationConfigurerAdapter

  • WebSecurityConfigurer

我们分别来看。

1.1 SecurityConfigurerAdapter

SecurityConfigurerAdapter 实现了 SecurityConfigurer 接口,我们所使用的大部分的 xxxConfigurer 也都是 SecurityConfigurerAdapter 的子类。

SecurityConfigurerAdapter 在 SecurityConfigurer 的基础上,还扩展出来了几个非常好用的方法,我们一起来看下:

public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder>

implements SecurityConfigurer<O, B> {

private B securityBuilder;

private CompositeObjectPostProcessor objectPostProcessor = new CompositeObjectPostProcessor();

public void init(B builder) throws Exception {

}

public void configure(B builder) throws Exception {

}

public B and() {

return getBuilder();

}

protected final B getBuilder() {

if (securityBuilder == null) {

throw new IllegalStateException(“securityBuilder cannot be null”);

}

return securityBuilder;

}

@SuppressWarnings(“unchecked”)

protected T postProcess(T object) {

return (T) this.objectPostProcessor.postProcess(object);

}

public void addObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {

this.objectPostProcessor.addObjectPostProcessor(objectPostProcessor);

}

public void setBuilder(B builder) {

this.securityBuilder = builder;

}

private static final class CompositeObjectPostProcessor implements

ObjectPostProcessor {

private List<ObjectPostProcessor<?>> postProcessors = new ArrayList<>();

@SuppressWarnings({ “rawtypes”, “unchecked” })

public Object postProcess(Object object) {

for (ObjectPostProcessor opp : postProcessors) {

Class<?> oppClass = opp.getClass();

Class<?> oppType = GenericTypeResolver.resolveTypeArgument(oppClass,

ObjectPostProcessor.class);

if (oppType == null || oppType.isAssignableFrom(object.getClass())) {

object = opp.postProcess(object);

}

}

return object;

}

private boolean addObjectPostProcessor(

ObjectPostProcessor<?> objectPostProcessor) {

boolean result = this.postProcessors.add(objectPostProcessor);

postProcessors.sort(AnnotationAwareOrderComparator.INSTANCE);

return result;

}

}

}

  1. CompositeObjectPostProcessor 首先一开始声明了一个 CompositeObjectPostProcessor 实例,CompositeObjectPostProcessor 是 ObjectPostProcessor 的一个实现,ObjectPostProcessor 本身是一个后置处理器,该后置处理器默认有两个实现,AutowireBeanFactoryObjectPostProcessor 和 CompositeObjectPostProcessor。其中 AutowireBeanFactoryObjectPostProcessor 主要是利用了 AutowireCapableBeanFactory 对 Bean 进行手动注册,因为在 Spring Security 中,很多对象都是手动 new 出来的,这些 new 出来的对象和容器没有任何关系,利用 AutowireCapableBeanFactory 可以将这些手动 new 出来的对象注入到容器中,而 AutowireBeanFactoryObjectPostProcessor 的主要作用就是完成这件事;CompositeObjectPostProcessor 则是一个复合的对象处理器,里边维护了一个 List 集合,这个 List 集合中,大部分情况下只存储一条数据,那就是 AutowireBeanFactoryObjectPostProcessor,用来完成对象注入到容器的操作,如果用户自己手动调用了 addObjectPostProcessor 方法,那么 CompositeObjectPostProcessor 集合中维护的数据就会多出来一条,在 CompositeObjectPostProcessor#postProcess 方法中,会遍历集合中的所有 ObjectPostProcessor,挨个调用其 postProcess 方法对对象进行后置处理。

  2. and 方法,该方法返回值是一个 securityBuilder,securityBuilder 实际上就是 HttpSecurity,我们在 HttpSecurity 中去配置不同的过滤器时,可以使用 and 方法进行链式配置,就是因为这里定义了 and 方法并返回了 securityBuilder 实例。

这便是 SecurityConfigurerAdapter 的主要功能,后面大部分的 xxxConfigurer 都是基于此类来实现的。

1.2 GlobalAuthenticationConfigurerAdapter

GlobalAuthenticationConfigurerAdapter 看名字就知道是一个跟全局配置有关的东西,它本身实现了 SecurityConfigurerAdapter 接口,但是并未对方法做具体的实现,只是将泛型具体化了:

@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 中的泛型,现在明确成了 AuthenticationManager 和 AuthenticationManagerBuilder。所以 GlobalAuthenticationConfigurerAdapter 的实现类将来主要是和配置 AuthenticationManager 有关。当然也包括默认的用户名密码也是由它的实现类来进行配置的。

我们在 Spring Security 中使用的 AuthenticationManager 其实可以分为两种,一种是局部的,另一种是全局的,这里主要是全局的配置。

1.3 WebSecurityConfigurer

还有一个实现类就是 WebSecurityConfigurer,这个可能有的小伙伴比较陌生,其实他就是我们天天用的 WebSecurityConfigurerAdapter 的父接口。

所以 WebSecurityConfigurer 的作用就很明确了,用户扩展用户自定义的配置。

SecurityConfigurer 默认主要是这三个实现,考虑到大多数的过滤器配置都是通过 SecurityConfigurerAdapter 进行扩展的,因此我们今天就通过这条线进行展开。另外两条线松哥也将撸两篇文章和大家介绍。

2. SecurityConfigurerAdapter


SecurityConfigurerAdapter 的实现主要也是三大类:

  • UserDetailsAwareConfigurer

  • AbstractHttpConfigurer

  • LdapAuthenticationProviderConfigurer

考虑到 LDAP 现在使用很少,所以这里我来和大家重点介绍下前两个。

2.1 UserDetailsAwareConfigurer

这个配置类看名字大概就知道这是用来配置用户类的。

AbstractDaoAuthenticationConfigurer

AbstractDaoAuthenticationConfigurer 中所做的事情比较简单,主要是构造了一个默认的 DaoAuthenticationProvider,并为其配置 PasswordEncoder 和 UserDetailsService。

UserDetailsServiceConfigurer

UserDetailsServiceConfigurer 重写了 AbstractDaoAuthenticationConfigurer 中的 configure 方法,在 configure 方法执行之前加入了 initUserDetailsService 方法,以方便开发展按照自己的方式去初始化 UserDetailsService。不过这里的 initUserDetailsService 方法是空方法。

UserDetailsManagerConfigurer

UserDetailsManagerConfigurer 中实现了 UserDetailsServiceConfigurer 中定义的 initUserDetailsService 方法,具体的实现逻辑就是将 UserDetailsBuilder 所构建出来的 UserDetails 以及提前准备好的 UserDetails 中的用户存储到 UserDetailsService 中。

该类同时添加了 withUser 方法用来添加用户,同时还增加了一个 UserDetailsBuilder 用来构建用户,这些逻辑都比较简单,小伙伴们可以自行查看。

JdbcUserDetailsManagerConfigurer

JdbcUserDetailsManagerConfigurer 在父类的基础上补充了 DataSource 对象,同时还提供了相应的数据库查询方法。

InMemoryUserDetailsManagerConfigurer

InMemoryUserDetailsManagerConfigurer 在父类的基础上重写了构造方法,将父类中的 UserDetailsService 实例定义为 InMemoryUserDetailsManager。

DaoAuthenticationConfigurer

DaoAuthenticationConfigurer 继承自 AbstractDaoAuthenticationConfigurer,只是在构造方法中修改了一下 userDetailsService 而已。

有小伙伴可能要问了,JdbcUserDetailsManagerConfigurer 或者 InMemoryUserDetailsManagerConfigurer,到底在哪里可以用到呀?

松哥给大家举一个简单的例子:

@Configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication().withUser(“javaboy”)

.password(“{noop}123”)

.roles(“admin”);

}

@Override

protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()

.anyRequest().authenticated()

//省略

}

}

当你调用 auth.inMemoryAuthentication 进行配置时,实际上调用的就是 InMemoryUserDetailsManagerConfigurer。

这下明白了吧!

2.2 AbstractHttpConfigurer

AbstractHttpConfigurer 这一派中的东西非常多,我们所有的过滤器配置,都是它的子类,我们来看下都有哪些类?

可以看到,它的实现类还是非常多的。

这么多实现类,松哥就不一一给大家介绍了,我挑一个常用的 FormLoginConfigurer 来给大家详细介绍,只要大家把这个理解了,其他的照猫画虎就很好理解了。

我们一个一个来看。

2.2.1 AbstractHttpConfigurer

AbstractHttpConfigurer 继承自 SecurityConfigurerAdapter,并增加了两个方法,disable 和 withObjectPostProcessor:

public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T, B>, B extends HttpSecurityBuilder>

总结

就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的offer! 越努力越幸运!

金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。

三面蚂蚁核心金融部,Java开发岗(缓存+一致性哈希+分布式)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。**

[外链图片转存中…(img-ol66deG9-1715438002798)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值