1. 前言

在上一篇我们对AuthenticationManager的初始化的细节进行了分析,其中里面有一段代码引起了不少同学的注意:

  ApplicationContext context = http.getSharedObject(ApplicationContext.class);
CaptchaAuthenticationProvider captchaAuthenticationProvider = context.getBean("captchaAuthenticationProvider", CaptchaAuthenticationProvider.class);

上面直接从HttpSecurity对象中获取到Spring的应用上下文对象ApplicationContext,它是怎么做到的呢?SharedObject又是个什么概念?今天就来搞清楚这个问题。

2. SharedObject

在Spring Security中SharedObject既不是对象也不是接口,而是某一类“可共享”的对象的统称。

顾名思义,SharedObject的意思是可共享的对象。它的作用是如果一些对象你希望在不同的作用域配置中共享它们就把这些对象变成SharedObject,有点分布式对象的感觉。为了更加便于你理解,下面是相关的体系结构:

AbstractConfiguredSecurityBuilder或者HttpSecurityBuilder的实现类才具有操作SharedObject的能力。一种是注册SharedObject,另一种是获取SharedObject。

SharedObject的注册

SharedObject会以其Class类型为Key,实例为Value存储到一个HashMap<Class<?>,Object>中,具体可看HttpSecurity源码。它的注册分为两个部分,第一是HttpSecurity初始化的时候装配进去的。我们来看看:

我们熟知的AuthenticationManagerBuilder在这里被共享。

还有一部分是在所有的HttpSecurityBuilder对象初始化时注册的。它初始化和配置都是由SecurityConfigurer来完成的:

public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {

   void init(B builder) throws Exception;

   void configure(B builder) throws Exception;
}

上面两个方法分别用来初始化和配置HttpSecurityBuilder。比如我们熟知的WebSecurityConfigurerAdapter就是用来配置HttpSecurity的,在其init方法中我们可以找到相关的代码:

private Map<Class<?>, Object> createSharedObjects() {
Map<Class<?>, Object> sharedObjects = new HashMap<>();
sharedObjects.putAll(localConfigureAuthenticationBldr.getSharedObjects());
sharedObjects.put(UserDetailsService.class, userDetailsService());
sharedObjects.put(ApplicationContext.class, context);
sharedObjects.put(ContentNegotiationStrategy.class, contentNegotiationStrategy);
sharedObjects.put(AuthenticationTrustResolver.class, trustResolver);
return sharedObjects;
}

这也是我在文章开头可以获取到ApplicationContext的根本原因。

SharedObject的获取和使用

我们能获取到哪些被标记为SharedObject类呢?SecurityConfigurer有很多实现,这些实现都是用来配置一些特定的同认证授权相关的功能的。比如OAuth2ClientConfigurer用来配置OAuth2客户端的,它里面就将常用的一些对象设置为SharedObject:

public OAuth2ClientConfigurer<B> clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) {
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository);
return this;
}

当你在HttpSecurity的配置中的其它地方需要用到ClientRegistrationRepository时,你可以直接通过getSharedObject获取,就像文章开头一样,而不用在去写一些获取方法了。

3. 总结

SharedObject是Spring Security提供的一个非常好用的功能,如果你在不同的地方需要对一个对象重复使用就可以将它注册为SharedObject,甚至直接注入Spring IoC像开头那样获取就可以了。这个特性能够简化配置,提高代码的可读性,也为Spring Security的DSL特性打下了基础。好了今天的分享就到这里,我是:码农小胖哥,多多关注,获取更多实用的编程干货。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Spring Security 实战干货:分布式对象SharedObject的更多相关文章

  1. Spring Security 实战干货:如何实现不同的接口不同的安全策略

    1. 前言 欢迎阅读 Spring Security 实战干货 系列文章 .最近有开发小伙伴提了一个有趣的问题.他正在做一个项目,涉及两种风格,一种是给小程序出接口,安全上使用无状态的JWT Toke ...

  2. Spring Security 实战干货:理解AuthenticationManager

    1. 前言 我们上一篇介绍了UsernamePasswordAuthenticationFilter的工作流程,留下了一个小小的伏笔,作为一个Servlet Filter应该存在一个doFilter实 ...

  3. Spring Security 实战干货:图解用户是如何登录的

    1. 前言 欢迎阅读Spring Security 实战干货系列文章,在集成Spring Security安全框架的时候我们最先处理的可能就是根据我们项目的实际需要来定制注册登录了,尤其是Http登录 ...

  4. Spring Security 实战干货:客户端OAuth2授权请求的入口

    1. 前言 在Spring Security 实战干货:OAuth2第三方授权初体验一文中我先对OAuth2.0涉及的一些常用概念进行介绍,然后直接通过一个DEMO来让大家切身感受了OAuth2.0第 ...

  5. Spring Security 实战干货:OAuth2授权请求是如何构建并执行的

    在Spring Security 实战干货:客户端OAuth2授权请求的入口中我们找到了拦截OAuth2授权请求入口/oauth2/authorization的过滤器OAuth2Authorizati ...

  6. Spring Security 实战干货:使用 JWT 认证访问接口

    (转载)原文链接:https://my.oschina.net/10000000000/blog/3127268 1. 前言 欢迎阅读Spring Security 实战干货系列.之前我讲解了如何编写 ...

  7. Spring Security 实战干货: 简单的认识 OAuth2.0 协议

    1.前言 欢迎阅读 Spring Security 实战干货 系列文章 .OAuth2.0 是近几年比较流行的授权机制,对于普通用户来说可能每天你都在用它,我们经常使用的第三方登录大都基于 OAuth ...

  8. Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...

  9. Spring Security 实战干货:实现自定义退出登录

    文章目录 1. 前言 2. 我们使用 Spring Security 登录后都做了什么 2. 退出登录需要我们做什么 3. Spring Security 中的退出登录 3.1 LogoutFilte ...

  10. Spring Security 实战干货:OAuth2第三方授权初体验

    1. 前言 Spring Security实战干货系列 现在很多项目都有第三方登录或者第三方授权的需求,而最成熟的方案就是OAuth2.0授权协议.Spring Security也整合了OAuth2. ...

随机推荐

  1. Protobuf简单类型直接反序列化方法

    我有一个想法,有一个能够进行跨平台的高性能数据协议规范,能够让数据在两个不同的程序之间进行读取,最好能够支持直接将object序列化,那就完美了. 目标 支持任意Object序列化 支持从类似Syst ...

  2. Python之selenium创建多个标签页

    最近在做一个项目,需要用到cookies登录,想法是,在同一个浏览器下,打开两个标签页进行.让其自动获取cookies,先记录,不行的话,到时候再手动加载cookies. 1 ''' 2 #selen ...

  3. 【electron+vue3+ts实战便笺exe】二、electron+vue3开发内容

    不要让自己的上限成为你的底线 本来以为有万字的..没想到才堪堪近6000字.为了水文的嫌疑,只挑了重点的地方讲,比如component内的组件就挑了右键弹窗去说明,建议在看本文的时候边查看项目,有不懂 ...

  4. jrebel 启动失败的处理

    jrebel 启动失败的处理 今天使用 jrebel 启动项目的时候,突然啥日志都没有,只有一句Disconnected from the target VM, address: '127.0.0.1 ...

  5. 在 easyui中获取form表单中所有提交的数据 拼接到table列表中

    form表单===== <!-- 并用药品填写信息弹框 --> <div id="usingProdctMsgDiv" style="display: ...

  6. Cassandra与Kafka的集成

    Cassandra和Kafka经常一起用于微服务架构中.本文将介绍几种Cassandra和Kafka常见的集成模式.   简介   如果您的开发团队乐于接纳微服务架构的优点,那么您就会了解到,Kafk ...

  7. vue 导入.md文件(markdown转HTML)

    前言 刚接到这个需求的时候,觉得很简单(的确很简单)但是这玩意的坑真的也让人无奈. 网上找了很多的资料,都没有写出痛点(这就很难过了).通过实践并且在我们项目中平稳运行,想分享给后面的人 我的博客上也 ...

  8. java: Compilation failed: internal java compiler error

    IDEA 编译项目出现java: Compilation failed: internal java compiler error 原因:  项目Java版本不一致 解决办法:  点击FIle> ...

  9. SpringBoot 获取微信小程序openid

    最近做一个项目用到小程序,为了简化用户啊登录,通过获取小程序用户的openid来唯一标示用户. 1.官方教程 2.具体步骤 3.具体实现 4.可能出现的错误 5.代码下载 1.官方教程 先来看看官方怎 ...

  10. mysql远程访问被拒绝问题

    远程连接MySql数据库时: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 远 ...