DefaultTokenServices源码

文章目录

  • DefaultTokenServices
    • 实现的接口
      • AuthorizationServerTokenServices
      • ResourceServerTokenServices
      • ConsumerTokenServices
    • 代码
      • 属性定义
        • createAccessToken(OAuth2Authentication)
          • createRefreshToken(OAuth2Authentication)

DefaultTokenServices

DefaultTokenServices是掌握spring security oauth2 颁发令牌的重要实现,它有着发放令牌存储令牌令牌校验令牌撤销等功能;

DefaultTokenServices实现了3个接口:AuthorizationServerTokenServicesResourceServerTokenServicesConsumerTokenServices

实现的接口

AuthorizationServerTokenServices

授权服务器令牌服务接口

// 创建令牌, 根据 OAuth2Authentication 生成 OAuth2AccessToken 访问令牌对象
OAuth2AccessToken createAccessToken(OAuth2Authentication authentication)// 刷新令牌
OAuth2AccessToken refreshAccessToken(String refreshToken, TokenRequest tokenRequest)// 查询令牌, 查询发放给指定 OAuth2Authentication对象的令牌
OAuth2AccessToken getAccessToken(OAuth2Authentication authentication);

ResourceServerTokenServices

资源服务器令牌服务接口

// 根据令牌 返回 OAuth2Authentication 对象
OAuth2Authentication loadAuthentication(String accessToken)// 根据令牌 获取 访问令牌 对象
OAuth2AccessToken readAccessToken(String accessToken)

ConsumerTokenServices

// 撤销令牌
boolean revokeToken(String tokenValue);

代码

属性定义

public class DefaultTokenServices  implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean {// 刷新里令牌的有效期, 默认30天int refreshTokenValiditySeconds = 60 * 60 * 24 * 30;        // 访问令牌有效期, 默认12小时int accessTokenValiditySeconds = 60 * 60 * 12;              // 是否支持刷新令牌boolean supportRefreshToken = false;                          // 刷新令牌是否可重用boolean reuseRefreshToken = true;// 令牌存储器, 显然, 当前令牌服务把存储令牌的操作和查询令牌的操作交给了TokenStore来处理TokenStore tokenStore;// 客户端服务ClientDetailsService clientDetailsService;// 令牌增强器TokenEnhancer accessTokenEnhancer;// 认证管理器AuthenticationManager authenticationManagerpublic void afterPropertiesSet() throws Exception {// tokenStore不能为空Assert.notNull(tokenStore, "tokenStore must be set");}}
createAccessToken(OAuth2Authentication)

颁发令牌

@Transactional
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) {// 根据 OAuth2Authentication 用户授权信息, 使用 tokenStore 查询 OAuth2AccessToken 访问令牌信息OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication);// 刷新令牌OAuth2RefreshToken refreshToken = null;// 如果 查询得到的 OAuth2AccessToken 访问令牌信息 存在if (existingAccessToken != null) {// 如果 查询得到的 OAuth2AccessToken 访问令牌信息 虽然存在, 但是已过期if (existingAccessToken.isExpired()) {// 如果 该过期的 OAuth2AccessToken 访问令牌信息 的刷新令牌 不为空if (existingAccessToken.getRefreshToken() != null) {// 记录已过期的刷新令牌refreshToken = existingAccessToken.getRefreshToken();// 使用 tokenStore 移除此刷新令牌tokenStore.removeRefreshToken(refreshToken);}// 使用 tokenStore 移除 该过期的 OAuth2AccessToken 访问令牌信息tokenStore.removeAccessToken(existingAccessToken);}else {// 查询得到的 OAuth2AccessToken 访问令牌信息 存在, 且没有过期, 将仍然返回此 令牌信息// 在返回前, 重新保存一下 OAuth2AccessToken 令牌信息 和 OAuth2Authentication 用户授权信息tokenStore.storeAccessToken(existingAccessToken, authentication);return existingAccessToken;}}// 如果 前面 未查询到 OAuth2AccessToken 访问令牌信息 //     或是 查询到的 OAuth2AccessToken 访问令牌信息 无 刷新令牌(此时, 令牌信息已过期)if (refreshToken == null) {// 创建刷新令牌refreshToken = createRefreshToken(authentication);}else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {// 前面 查询到的 OAuth2AccessToken 访问令牌信息 的 刷新令牌 类型为 ExpiringOAuth2RefreshToken,ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken;if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {// 并且该刷新令牌也已过期, 则也创建刷新令牌refreshToken = createRefreshToken(authentication);}}// 至此, 刷新令牌可以确定了, 并且确定需要创建令牌了// 创建令牌, 传入 OAuth2Authentication 用户授权信息 和 刷新令牌信息(这个刷新令牌信息有肯能是旧的)OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);// 使用 tokenStore 保存 OAuth2AccessToken 令牌信息 和 OAuth2Authentication 用户授权信息 的关系tokenStore.storeAccessToken(accessToken, authentication);// 获取 令牌信息 的刷新令牌 refreshToken = accessToken.getRefreshToken();if (refreshToken != null) {// 如果刷新令牌不为空, 使用 tokenStore 保存 OAuth2RefreshToken 令牌信息 和 OAuth2Authentication 用户授权信息 的关系tokenStore.storeRefreshToken(refreshToken, authentication);}// 返回 令牌信息return accessToken;}
createRefreshToken(OAuth2Authentication)

创建刷新令牌

private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {// 是否支持刷新令牌if (!isSupportRefreshToken(authentication.getOAuth2Request())) {return null;}// 获取 刷新令牌的有效时间int validitySeconds = getRefreshTokenValiditySeconds(authentication.getOAuth2Request());// uuid作为刷新令牌值String value = UUID.randomUUID().toString();// 如果 刷新令牌的有效时间 不为空, 则使用 DefaultExpiringOAuth2RefreshToken 作为刷新令牌的实现,// 并设置 刷新令牌值 和 刷新令牌过期时间if (validitySeconds > 0) {return new DefaultExpiringOAuth2RefreshToken(value, new Date(System.currentTimeMillis()+ (validitySeconds * 1000L)));}// 如果 刷新令牌的有效时间 为空, 则使用 DefaultOAuth2RefreshToken 作为刷新令牌的实现,// 并设置 刷新令牌值, 没有刷新令牌过期时间return new DefaultOAuth2RefreshToken(value);
}/* 如果有设置 clientDetailsService, 那么查询客户端对应的ClientDetails, 如果该客户端支持刷新令牌,那么直接返回支持, 否则, 由 DefaultTokenServices 的 supportRefreshToken 属性来确定
*/
protected boolean isSupportRefreshToken(OAuth2Request clientAuth) {if (clientDetailsService != null) {ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());return client.getAuthorizedGrantTypes().contains("refresh_token");}return this.supportRefreshToken;
}/* 如果有设置 clientDetailsService, 那么查询客户端对应的ClientDetails, 如果该客户端有设置刷新令牌有效时间,那么直接返回该有效时间, 否则, 由 DefaultTokenServices 的 refreshTokenValiditySeconds 属性来确定
*/
protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) {if (clientDetailsService != null) {ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());Integer validity = client.getRefreshTokenValiditySeconds();if (validity != null) {return validity;}}return refreshTokenValiditySeconds;
}

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

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

相关文章

Unity Shader基础知识的入门了解

目录 1、Unity 中的shader 里面的所谓的顶点坐标,用通俗的语言讲解一下? 什么是顶点? 顶点坐标是什么? 通俗解释顶点坐标 在Unity Shader中的顶点坐标 在Shader中使用顶点坐标 总结 2、顶点UV1/UV2 是什么意思,用通俗的语…

LeetCode116.填充每个节点的下一个右侧节点指针

法一: /* // Definition for a Node. class Node { public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left…

AI大模型学习(非常详细)零基础入门到精通,收藏这一篇就够了

前言 随着人工智能技术的快速发展,AI大模型学习正成为一项备受关注的研究领域。为了提高模型的准确性和效率,研究者们需要具备深厚的数学基础和编程能力,并对特定领域的业务场景有深入的了解。通过不断优化模型结构和算法,AI大模…

python如何输入回车

Python默认遇到回车的时候,输入结束。所以我们需要更改这个提示符,在遇到空行的时候,输入才结束。 raw_input就是从标注输入读取输入,输入的是什么就是什么。 文档解释: The function then reads a line from input,…

软考 系统架构设计师系列知识点之杂项集萃(30)

接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(29) 第47题 安全性是根据系统可能收到的安全威胁的类型来分类的。其中,( )保证信息不泄露给未授权的用户、实体或过程;( &a…

RabbitMQ 2万字面试题及参考答案

目录 什么是RabbitMQ? RabbitMQ的Broker、Exchange、Queue、Binding、Routing Key、VHost分别是什么? RabbitMQ中的生产者(Producer)和消费者(Consumer)的角色是什么? 什么是RabbitMQ的Channel? RabbitMQ支持哪些消息传输保证层级(如At most once, At least once…

不相同的字符串 acm模式刷题

题目描述 给定一个只包含小写字母的字符串,每次操作可以将两个相同的字母删除,然后在字符串的末尾新增任意一个小写字母。请问最少需要多少次操作,才能使字符串中所有的字母都不相同。 输入描述 第一行是一个整数 N,表示后续会有 …

UFS协议入门-分层结构

写在前面:本文参考UFS jedec3.1,本文思维导图如下 1. 分层概述 UFS协议分为3层,从上至下分别是:应用层(UAP),传输层(UTP),互联层(UIC),具体结构如下图所示。 2.1 应用层 在应用层(UAP)中,包括:UFS指令集(UCS),设备管理器(Device Manager),任务管理器(Task Manager…

代码随想录算法训练营第三十二天|122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

LeetCode 122.买卖股票的最佳时机II 题目链接:122.买卖股票的最佳时机II 踩坑:差点陷入不必要的细节,比如怎么表现买入卖出,怎么体现同一天买入卖出 思路:这里的股票买卖是看了天眼,明天的涨跌今天就知道…

基于FPGA的图像一维FFT变换IFFT逆变换verilog实现,包含tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 fpga仿真结果 matlab调用FPGA的仿真结果进行图像显示 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 ......................…

检测数据类型的方法有哪些

1.typeof,问题是对null的结果是object console.log(typeof 42); // "number" console.log(typeof hello); // "string" console.log(typeof true); // "boolean" console.log(typeof undefined); // "undefined" console.…

Knife4j 生成 API 文档

文章目录 Knife4j 简介使用步骤Knife4j 常用注解的列表案例可能遇到报错 Knife4j 简介 Knife4j 是一个增强的 Swagger 文档生成工具,提供了更加友好的界面和更多功能,使得 API 文档更加美观且易于使用。它是基于 Spring Boot 和 Swagger 进行封装的&…

2024年二级建造师考试题库及答案

一、单选题 11.对于同类型产品规格多、工序重复、工作量小的施工过程,编制人工定额宜采用的方法是()。 A.经验估算法 B.技术测定法 C.统计分析法 D.比较类推法 答案:D 解析:本题考察的是"制定人工定额的常…

Xcode 安装17.5 simulator 总是失败

升级到xcode15.4后需要安装ios17.5模拟器 但是在下载过程中会遇到报错 : The network connection is lost 解决方案: 先将模拟器下载到本地 Xcode 安装17.5 simulator 下载地址: Sign In - Applhttps://developer.apple.com/download/all/?qXcode 下…

C# WPF入门学习主线篇(十五)—— DockPanel布局容器

C# WPF入门学习主线篇(十五)—— DockPanel布局容器 欢迎来到C# WPF入门学习系列的第十五篇。在前几篇文章中,我们探讨了 Canvas、StackPanel 和 WrapPanel 布局容器及其使用方法。本篇博客将介绍另一种强大且常用的布局容器——DockPanel。…

07.组件间通信-provide-inject(祖孙通信)

组件间通信-provide-inject&#xff08;祖孙通信&#xff09; 父组件&#xff1a; <template><div class"father"><h3>父组件</h3><h4>银子&#xff1a;{{ money }}万元</h4><h4>车子&#xff1a;一辆{{car.brand}}车&am…

【计算机网络】P3 计算机网络协议、接口、服务的概念、区别以及计算机网络提供的三种服务方式

目录 协议什么是协议协议是水平存活的协议的组成 接口服务服务是什么服务原语 协议与服务的区别计算机网络提供的服务的三种方式面向连接服务与无连接服务可靠服务与不可靠服务有应答服务与无应答服务 协议 什么是协议 协议&#xff0c;就是规则的集合。 在计算机网络中&…

# 梯影传媒T6投影仪刷机方法及一些刷机工具链接

梯影传媒T6投影仪刷机方法及一些刷机工具链接 文章目录 梯影传媒T6投影仪刷机方法及一些刷机工具链接1、安装驱动程序2、备份设备rom【boot、system】3、还原我要刷进设备的rom【system】4、打开开发者模式以便于安装apk5、root设备6、更多好链接&#xff1a; 梯影传媒T6使用的…

Redis系列-4 Redis集群介绍

Redis集群 Redis提供了持久化能力&#xff0c;保证了重启不会丢失数据&#xff1b;但Redis重启至完全恢复期间&#xff0c;缓存不可用。另外&#xff0c;对于高并发场景下&#xff0c;单点Redis服务器的性能不能满足吞吐量要求&#xff0c;需要进行横向扩展。此时&#xff0c;…