@EnableAuthorizationServer授权服务注解源码分析

文章目录

  • 学习参考
  • @EnableAuthorizationServer
    • AuthorizationServerEndpointsConfiguration
      • TokenKeyEndpointRegistrar
      • endpoints&clientDetailsService&configurers
      • AuthorizationEndpoint授权端点
      • TokenEndpoint令牌端点

学习参考

Spring Security框架配置运行流程完整分析 - 【必看】

Security OAuth2 授权 & JWT

OAuth2授权流程和源码解析 - 自己总结 - 有道笔记~

Spring Security整合Gitee第三方登录

第三方登录源码梳理 - 自己总结 - 有道笔记~

Security OAuth2 SSO单点登录(一)

Security OAuth2 SSO单点登录源码剖析 - 自己总结 - 有道笔记~

@EnableAuthorizationServer

@EnableAuthorizationServer用于开启授权服务器,它使用@Import注解引入了如下2个配置类:

  • AuthorizationServerEndpointsConfiguration

    • 授权服务器端点配置类
    • 用于引入授权端点、令牌端点、校验令牌端点、授权页面端点、FrameworkEndpoint端点处理器映射器、授权服务器令牌服务、撤销令牌服务、TokenKey令牌密钥端点等组件;
    • 内部创建了1个AuthorizationServerEndpointsConfigurer作为成员变量endpoints,并且会注入容器中所有的AuthorizationServerConfigurer来对该endpoints成员变量进行配置,并且注入容器中的clientDetailsService设置到endpoints中。
    • 当前AuthorizationServerEndpointsConfiguration配置类中的定义的很多端点组件所用到的其它组件都是直接从endpoints成员变量中拿的。
  • AuthorizationServerSecurityConfiguration

    • 授权服务器安全配置类继承自WebSecurityConfigurerAdapter,order为0,其中WebSecurityConfigurerAdapter的order默认为100;重写了父类WebSecurityConfigurerAdapter的configure(AuthenticationManagerBuilder)方法,使得disableLocalConfigureAuthenticationBldr属性为false,即不会从spring容器中获取全局的认证管理器,而是使用localConfigureAuthenticationBldr来构建认证管理器作为ProviderManager的parent属性;
    • 使用@Import引入了ClientDetailsServiceConfiguration客户端服务配置类和AuthorizationServerEndpointsConfiguration授权服务器端点配置类,所以 授权服务器安全配置类 默认就引入了授权服务器端点配置类
    • 引入的ClientDetailsServiceConfiguration客户端服务配置类中定义了1个ClientDetailsService的bean;
    • 自动注入容器中所有的AuthorizationServerConfigurer,并对自动注入的ClientDetailsService的bean进行配置;
    • 在重写的configure(HttpSecurity)方法中创建了1个AuthorizationServerSecurityConfigurer授权服务器安全配置器,使用自动注入的所有AuthorizationServerConfigurer对该创建的AuthorizationServerSecurityConfigurer授权服务器安全配置器进行配置,并将此权服务器安全配置器添加到HttpSecurity中;这个AuthorizationServerSecurityConfigurer授权服务器安全配置器的作用就是用来配置HttpSecurity的。如果AuthorizationServerEndpointsConfiguration授权服务器端点配置类中的endpoints属性(即AuthorizationServerEndpointsConfigurer配置器)的userDetailsServiceOverride为false(即userDetailsService还未具体设置),那就默认从HttpSecurity的sharedObjects中获取UserDetailsService类型对应的值设置到uthorizationServerEndpointsConfiguration授权服务器端点配置类中的endpoints属性的userDetailsService属性中;为HttpSecurity添加配置类,配置tokenEndpointPath、tokenKeyPath、checkTokenPath路径访问权限和该HttpSecurity仅匹配此3个路径的请求;关闭会话配置类;将自动注入的clientDetailsService添加到HtppSecurity的sharedObjects属性中。

AuthorizationServerEndpointsConfiguration

授权服务器端点配置类

TokenKeyEndpointRegistrar

AuthorizationServerEndpointsConfiguration中使用了@Import注解引入了TokenKeyEndpointRegistrar,这个TokenKeyEndpointRegistrar会寻找容器中的JwtAccessTokenConverter类型的bean,找到第一个JwtAccessTokenConverter类型的bean作为TokenKeyEndpoint的构造方法的参数,于是就注册了处理/oauth/token_key令牌公钥的端点

@Configuration
@Import(TokenKeyEndpointRegistrar.class)  // 使用@Import注解引入了TokenKeyEndpointRegistrar
public class AuthorizationServerEndpointsConfiguration {

TokenKeyEndpointRegistrar实现了BeanDefinitionRegistryPostProcessor

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 找到第一个JwtAccessTokenConverter类型的bean作为TokenKeyEndpoint的构造方法的参数String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory,JwtAccessTokenConverter.class,false, false);if (names.length > 0) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TokenKeyEndpoint.class);builder.addConstructorArgReference(names[0]);registry.registerBeanDefinition(TokenKeyEndpoint.class.getName(), builder.getBeanDefinition());}
}

endpoints&clientDetailsService&configurers

创建了1个AuthorizationServerEndpointsConfigurer授权服务器端点配置器,它内部维护了很多端点组件需要的属性,需要通过容器中注入的AuthorizationServerConfigurer授权服务器配置器来对授权服务器端点配置器进行设置,这样后面当前AuthorizationServerEndpointsConfiguration类中定义的各个端点组件就可以从授权服务器配置器中拿到需要的属性来完成端点的配置了。

// 授权服务器端点配置器 作为 成员变量 endpoints
private AuthorizationServerEndpointsConfigurer endpoints = new AuthorizationServerEndpointsConfigurer();// 1. 注入容器中的 ClientDetailsService, 它定义在ClientDetailsServiceConfiguration
// 2. 由@EnableAuthorizationServer注解引入的AuthorizationServerSecurityConfiguration类使用@Import导入
@Autowired
private ClientDetailsService clientDetailsService;// 1. 注入容器中的所有授权服务器配置器
// 2. 一般来说, 我们就喜欢在使用@EnableAuthorizationServer注解所标注的类继承自AuthorizationServerConfigurerAdapter
@Autowired
private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();// 初始化方法
@PostConstruct
public void init() {// 1. 遍历所有的 AuthorizationServerConfigurer授权服务器配置器,// 2. 使用这些配置器来配置 AuthorizationServerEndpointsConfiguration类中定义的成员变量 endpoints// 3. endpoints的类型为 AuthorizationServerEndpointsConfigurer 授权服务器端点配置器for (AuthorizationServerConfigurer configurer : configurers) {try {configurer.configure(endpoints);} catch (Exception e) {throw new IllegalStateException("Cannot configure enpdoints", e);}}// 将注入的clientDetailsService设置给 endpoints授权服务器端点配置器endpoints.setClientDetailsService(clientDetailsService);
}

AuthorizationEndpoint授权端点

授权端点用来处理授权请求处理,用户发起对指定客户端的授权,跳转到授权页面,随后,用户同意该授权,发起授权请求,之后由授权模式所指定的类型的授权器处理授权请求。

@Bean
public AuthorizationEndpoint authorizationEndpoint() throws Exception {// 创建1个授权端点组件AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint();// 1. 这个getEndpointsConfigurer()就是去拿AuthorizationServerEndpointsConfiguration的endpoints属性的frameworkEndpointHandlerMapping属性// 2. 这个getEndpointsConfigurer()会确保endpoints属性的defaultTokenServices不为null, 否则会创建1个新的DefaultTokenServices作为令牌服务// 3. 这里的getFrameworkEndpointHandlerMapping()方法会确保endpoints的frameworkEndpointHandlerMapping不为null,否则会创建1个新的FrameworkEndpointHandlerMappingFrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();// 设置用户授权页面转发路径, 默认为: forward:/oauth/confirm_accessauthorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));// 从endpoints中去拿exceptionTranslator属性, 用来处理授权处理过程中的异常authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator());// 设置用户拒绝授权页面转发路径, 默认为: forward:/oauth/errorauthorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));// 从endpoints中去拿【tokenGranter授权器属性】, 用来支持不同授权模式的授权, 能支持哪些授权类型就是看这个属性// 会确保该授权器不为空, 否则会创建1个组合式的授权器authorizationEndpoint.setTokenGranter(tokenGranter());// 设置客户端信息服务authorizationEndpoint.setClientDetailsService(clientDetailsService);// 从endpoints中去拿authorizationCodeServices服务, 会确保该服务不为空, 否则创建1个InMemoryAuthorizationCodeServicesauthorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices());// 从endpoints中去拿requestFactory, 会确保该服务不为空, 否则创建1个DefaultOAuth2RequestFactoryauthorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());// 从endpoints中去拿requestValidator, 会确保该服务不为空, 否则创建1个DefaultOAuth2RequestValidatorauthorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());// 从endpoints中去拿userApprovalHandler, 会确保该服务不为空, 否则根据tokenStore的类型创建1个ApprovalStoreUserApprovalHandler或者TokenStoreUserApprovalHandlerauthorizationEndpoint.setUserApprovalHandler(userApprovalHandler());// 从endpoints中去拿redirectResolver, 会确保该服务不为空, 否则创建1个DefaultRedirectResolverauthorizationEndpoint.setRedirectResolver(redirectResolver());return authorizationEndpoint;
}

TokenEndpoint令牌端点

令牌端点用来处理颁发令牌的请求,当客户端根据授权模式发起获取令牌的请求时,由该端点处理

@Bean
public TokenEndpoint tokenEndpoint() throws Exception {// 创建令牌端点组件TokenEndpoint tokenEndpoint = new TokenEndpoint();// 设置客户端信息服务tokenEndpoint.setClientDetailsService(clientDetailsService);// 从endpoints中去拿exceptionTranslator属性, 用来处理授权处理过程中的异常tokenEndpoint.setProviderExceptionHandler(exceptionTranslator());// 从endpoints中去拿【tokenGranter授权器属性】, 用来支持不同授权模式的授权, 能支持哪些授权类型就是看这个属性// 会确保该授权器不为空, 否则会创建1个组合式的授权器tokenEndpoint.setTokenGranter(tokenGranter());// 从endpoints中去拿requestFactory, 会确保该服务不为空, 否则创建1个DefaultOAuth2RequestFactorytokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());// 从endpoints中去拿requestValidator, 会确保该服务不为空, 否则创建1个DefaultOAuth2RequestValidatortokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());// 从endpoints中去拿allowedTokenEndpointRequestMethods属性, 默认只支持post请求方式tokenEndpoint.setAllowedRequestMethods(allowedTokenEndpointRequestMethods());return tokenEndpoint;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【面试题-007】说一下JVM原理

JVM&#xff08;Java Virtual Machine&#xff0c;Java虚拟机&#xff09;是Java语言的一个核心概念&#xff0c;它允许Java代码在不同的操作系统上运行&#xff0c;而不需要为每个平台编写不同的代码。JVM是一种抽象的计算机&#xff0c;它实现了Java语言规范中的所有功能&…

Aethir: 破局算力瓶颈,构建AI时代去中心化云基础设施

科技的每一次飞跃都在重新塑造世界&#xff0c;而近年来&#xff0c;跨越式的技术革新再次引发了深刻的变革&#xff0c;那就是人工智能&#xff08;AI&#xff09;。 人工智能已然超越了此前的所有技术概念&#xff0c;成为了继互联网之后的下一个巨大浪潮。从自动驾驶汽车到…

每天复习一点小CTF知识(6.4)

NSSCTF/[FSCTF 2023]夜深人静的时候也会偷偷emo 直接爆破压缩包&#xff0c;先来数字 解压好&#xff0c;一个flag.mp3 mp3隐写&#xff0c;直接干 得一个txt文件直接开

宇泰485中继器光电隔离防雷 工业级RS485信号放大器 UT-2209正品

品牌&#xff1a;other/其他 型号&#xff1a;UT-2209 上市时间&#xff1a;2018-01-01 颜色分类&#xff1a;蓝色 信号延长器,工业级,高性能,RS-485光电隔离中继器,兼容RS-485标准,延长通信距离,即插即用. 性能特点: 内置光电隔离器及DC/DC隔离模块. 采用TVS瞬态电…

读书-《蛤蟆先生去看心理医生》

书名蛤蟆先生去看心理医生作者罗伯特戴博德状态阅读中简介该书借用《柳林风声》的故事主角蛤蟆先生&#xff0c;讲述了他接受心理咨询的故事。作者通过陷入抑郁的蛤蟆先生和心理咨询师苍鹭的互动&#xff0c;探索蛤蟆先生爱炫耀、自卑性格和抑郁情绪的来源&#xff0c;指出童年…

MicroSIP 使用笔记

下载 https://www.microsip.org/ 习惯下载 portable zip 日志 日志非常重要&#xff0c;对查问题有巨大帮助 编辑 microsip.ini&#xff0c; enableLog1 修改 listen 端口 编辑 microsip.ini&#xff0c;sourcePort5060 sip nat 编辑 sip 账号,"Allow IP Rewrite…

定积分求解举例

定积分是微积分中的一个重要概念&#xff0c;用于求解连续函数在某一区间上的面积或体积等问题。下面我将给出一个定积分求解的举例。 假设我们要求解函数 f(x)x2 在区间 [0,1] 上的定积分&#xff0c;即求解 ∫01​x2dx 求解步骤 1. 找出被积函数 f(x) 的原函数 F(x) 对于…

【Python】 如何在Python中使用小数步长值的`range()`函数?

在Python编程中&#xff0c;range()函数是一个非常常用的工具&#xff0c;它用于生成一个整数序列。然而&#xff0c;标准的range()函数只能接受整数作为步长值&#xff0c;这在某些情况下可能会限制其应用。幸运的是&#xff0c;Python提供了一些方法来实现使用小数步长的rang…

优思学院|六西格玛绿带与黑带知识体系的比较,哪个更适合你?

六西格玛作为一种广泛应用的质量管理方法&#xff0c;通过减少缺陷和变异来提高输出质量。为了实现这些目标&#xff0c;六西格玛采用数据驱动的DMAIC&#xff08;定义、测量、分析、改进、控制&#xff09;方法。在六西格玛的实施过程中&#xff0c;绿带和黑带是两个关键角色。…

【代码随想录】【算法训练营】【第28天】 [93]复原IP地址 [78]子集 [90]子集II

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 28&#xff0c;工作的周二~ 题目详情 [93] 复原 IP 地址 题目描述 93 复原 IP 地址 解题思路 前提&#xff1a;分割问题 思路&#xff1a;回溯算法&#xff0c;确定每次递归回溯的分割位置…

分布式文件系统-NFS

NFS 1. NFS工作原理 Linux中的网络文件系统NFS &#xff08;Network File System&#xff09;是一种分布式文件系统协议&#xff0c;它允许用户在网络上远程访问和操作文件&#xff0c;就好像这些文件存储在本地计算机上一样。NFS最初由Sun Microsystems在1980年代开发&#…

小短片创作-理论知识(五)

1、网格体绘制 1.UE5打开Megascan插件的材质混合器&#xff0c;创建混合材质&#xff0c;最多选择3个材质进行混合&#xff0c; 2.通过模式->网格体绘制&#xff0c;进入网格体绘制模式&#xff0c;通过select选择一个平面进行绘制&#xff0c;然后通过paint进行绘制&am…

关于线程池面试题,使用“豆包”训练答案

我提问&#xff1a; 问题描述 下面是一个有关线程池调度的面试真题&#xff0c;来自于疯狂创客圈社群&#xff1a; 一个线程池的核心线程数为10个&#xff0c;最大线程数为20个&#xff0c;阻塞队列的容量为30。现在提交45个 任务&#xff0c;每个任务的耗时为500毫秒。 请问&…

【Mac】Keyboard Maestro for Mac(键盘大师)软件介绍及安装教程

软件介绍 Keyboard Maestro for mac&#xff08;键盘大师&#xff09;是目前Mac OS平台上功能最为齐全的Mac键盘增强工具&#xff0c;它能将你的Keyboard作用发挥到极致&#xff0c;可以根据命令或计划自动执行简单或复杂的应用程序或网站&#xff0c;文本或图像。使用Keyboar…

python之* 和+

背景 python的* 和用法。 代码 >>> l [1, 2, 3] >>> l * 5 [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> 5 * abcd abcdabcdabcdabcdabcd 结论 Python程序员会默认序列是支持和*操作的。通常号两侧的序列由相同类型的数据所构成&#…

【TPAMI-2024】EfficientTrain++帮你降低网络训练的成本

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言论文更容易学习的模式:频域易于学习的模式:空间域统一的训练课程 EFFICIENTTRAIN计…

RIP v2路由安全认证综合实验

RIP v2路由安全认证综合实验 实验拓扑&#xff1a; 实验要求&#xff1a;通过认证防范攻击者获得通信设备的相关信息。 实验步骤&#xff1a; 1.完成基本配置 sys Enter system view, return user view with CtrlZ. [Huawei]sys AR1 [AR1]undo in e Info: Information center…

【电子书赠送福利】蘇小沐电子数据取证实务教程!风吹哪页读哪页,哪页不会撕哪页!

【电子书赠送福利】蘇小沐电子数据取证实务教程&#xff01;风吹哪页读哪页&#xff0c;哪页不会撕哪页&#xff01; 合并文章的时候才发现自己写了那么多&#xff0c;受限于时间&#xff0c;第一次合集版本只收录了已发博客的三分之二左右&#xff0c;暂时先这样&#xff01;…

外汇天眼:Bitpanda 扩大与德意志银行的合作

金融科技独角兽Bitpanda正在扩大与德意志银行的合作&#xff0c;为德国用户提供实时支付解决方案&#xff0c;以处理进出交易。 这种基于API的账户解决方案将使Bitpanda能够访问德国的IBAN账户&#xff0c;优化和增强用户体验&#xff0c;同时确保信任、速度和效率。 这只是Bi…

react-draft-wysiwyg富文本编辑器使用常见问题解答

记录一些常见的问题以及使用 1. 初始化赋值 import htmlToDraft from html-to-draftjs import { ContentState as DraftContentState } from draft-js import { EditorState,, convertToRaw } from draft-jsconst { initialContent } propsuseEffect(() > {if (initialCon…