【springsecurity oauth2授权中心】将硬编码的参数提出来放到 application.yml 里 P3
在application.yml里添加配置
application.yml
oauth2:client:id: clientsecret: secretauthentication-method: client_secret_basicgrant-types: authorization_code,refresh_tokenredirect-uris:- http://localhost:8081/login/oauth2/code/client- http://localhost:8081/login/oauth2/code/client2scopes: openid,userrequire-authorization-consent: truetoken:access-token-format: self_containedaccess-token-time-to-live: 2hserver:issuer-uri: http://localhost:9000
创建对应的配置类
如果用lombok没问题的话,可以选择lombok,我用lombok的@Data注解去自动生成getter, setter,idea里没有报错信息,但启动服务时报错,然后我就都给换成自己的写的getter,setter。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.time.Duration;
import java.util.List;@Component
@ConfigurationProperties(prefix = "oauth2")
public class OAuth2Properties {private Client client;private Token token;private Server server;public Client getClient() {return client;}public void setClient(Client client) {this.client = client;}public Token getToken() {return token;}public void setToken(Token token) {this.token = token;}public Server getServer() {return server;}public void setServer(Server server) {this.server = server;}
}class Client {private String id;private String secret;private String authenticationMethod;private List<String> grantTypes;private List<String> redirectUris;private List<String> scopes;private boolean requireAuthorizationConsent;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getSecret() {return secret;}public void setSecret(String secret) {this.secret = secret;}public String getAuthenticationMethod() {return authenticationMethod;}public void setAuthenticationMethod(String authenticationMethod) {this.authenticationMethod = authenticationMethod;}public List<String> getGrantTypes() {return grantTypes;}public void setGrantTypes(List<String> grantTypes) {this.grantTypes = grantTypes;}public List<String> getRedirectUris() {return redirectUris;}public void setRedirectUris(List<String> redirectUris) {this.redirectUris = redirectUris;}public List<String> getScopes() {return scopes;}public void setScopes(List<String> scopes) {this.scopes = scopes;}public boolean isRequireAuthorizationConsent() {return requireAuthorizationConsent;}public void setRequireAuthorizationConsent(boolean requireAuthorizationConsent) {this.requireAuthorizationConsent = requireAuthorizationConsent;}
}class Token {private String accessTokenFormat;private Duration accessTokenTimeToLive;public String getAccessTokenFormat() {return accessTokenFormat;}public void setAccessTokenFormat(String accessTokenFormat) {this.accessTokenFormat = accessTokenFormat;}public Duration getAccessTokenTimeToLive() {return accessTokenTimeToLive;}public void setAccessTokenTimeToLive(Duration accessTokenTimeToLive) {this.accessTokenTimeToLive = accessTokenTimeToLive;}
}class Server {private String issuerUri;public String getIssuerUri() {return issuerUri;}public void setIssuerUri(String issuerUri) {this.issuerUri = issuerUri;}
}
替换AuthorizationServerConfig类里硬编码的参数
注入配置类
private final OAuth2Properties oAuth2Properties;
publicAuthorizationServerConfig(OAuth2Properties oAuth2Properties) {this.oAuth2Properties = oAuth2Properties;
}
替换参数
@Beanpublic RegisteredClientRepository registeredClientRepository() {RegisteredClient.Builder clientBuilder = RegisteredClient.withId(UUID.randomUUID().toString()).clientId(oAuth2Properties.getClient().getId()).clientSecret(oAuth2Properties.getClient().getSecret()).clientAuthenticationMethod(new ClientAuthenticationMethod(oAuth2Properties.getClient().getAuthenticationMethod())).authorizationGrantTypes(grantTypes -> oAuth2Properties.getClient().getGrantTypes().forEach(gt -> grantTypes.add(new AuthorizationGrantType(gt))))
// .redirectUri("http://localhost:8081/login/oauth2/code/client").scope(OidcScopes.OPENID).scopes(scopes -> scopes.addAll(oAuth2Properties.getClient().getScopes())).clientSettings(ClientSettings.builder().requireAuthorizationConsent(oAuth2Properties.getClient().isRequireAuthorizationConsent()).build()).tokenSettings(TokenSettings.builder().accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED).accessTokenTimeToLive(oAuth2Properties.getToken().getAccessTokenTimeToLive()).build());// 添加所有配置的重定向URIoAuth2Properties.getClient().getRedirectUris().forEach(clientBuilder::redirectUri);return new InMemoryRegisteredClientRepository(clientBuilder.build());}@Beanpublic AuthorizationServerSettings authorizationServerSettings() {return AuthorizationServerSettings.builder().issuer(oAuth2Properties.getServer().getIssuerUri()).build();}
多redirect_uri处理
一个授权中心,多个应用服务器的情况下,所有应用服务器都会来请求这一个授权中心进行授权拿权限,但每个应用服务器都有自己的域名,这就会产生多种redirect_uri的问题
上面配置文件里和代码中已经处理好了,具体改动如下
oauth2:client:redirect-uris:- http://localhost:8081/login/oauth2/code/client- http://localhost:8081/login/oauth2/code/client2
@Beanpublic RegisteredClientRepository registeredClientRepository() {RegisteredClient.Builder clientBuilder = RegisteredClient.withId(UUID.randomUUID().toString()).clientId(oAuth2Properties.getClient().getId()).clientSecret(oAuth2Properties.getClient().getSecret())// ...;// 添加所有配置的重定向URI
oAuth2Properties.getClient().getRedirectUris().forEach(clientBuilder::redirectUri);return new InMemoryRegisteredClientRepository(clientBuilder.build());}
测试
配置了两个回调地址,就可以使用如下两个链接来进行测试,结果都能正常拿到code
- http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8081/login/oauth2/code/client&scope=user
- http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8081/login/oauth2/code/client2&scope=user
相关文章:
【springsecurity oauth2授权中心】将硬编码的参数提出来放到 application.yml 里 P3
在application.yml里添加配置 application.yml oauth2:client:id: clientsecret: secretauthentication-method: client_secret_basicgrant-types: authorization_code,refresh_tokenredirect-uris:- http://localhost:8081/login/oauth2/code/client- http://localhost:8081…...
【Ansible】批量管理 Windows自动化运维
一,前期准备 1,控制端(Linux)的要求 Ansible可以在安装了Python 2(2.7版)或Python 3(3.5及更高版本)的任何机器上运行。控制端计算机不支持Windows。 2,客户端&#x…...
AES-128、AES-192、AES-256 简介
AES(Advanced Encryption Standard) 是一种广泛使用的对称加密算法,由美国国家标准与技术研究院(NIST)于2001年正式采纳,用于替代旧的 DES 和 3DES。AES 基于 Rijndael 算法,支持 128 位、192 位…...
osxcross 搭建 macOS 交叉编译环境
1. osxcross 搭建 macOS 交叉编译环境 1. osxcross 搭建 macOS 交叉编译环境 1.1. 安装依赖1.2. 安装 osxcross 及 macOS SDK 1.2.1. 可能错误 1.3. 编译 cmake 类工程1.4. 编译 configure 类工程1.5. 单文件编译及其他环境编译1.6. 打包成 docker 镜像1.7. 使用 docker 编译 …...
联通余额查询接口
接口名称 1) 请求地址 https://ucbss.10010.cn/npfweb/NpfWeb/Mustpayment/getMustpayment?number13112345586&province051&commonBean.phoneNo13112345586&channelType101https://ucbss.10010.cn/npfweb/NpfWeb/Mustpayment/getMustpayment?number13112345586&…...
Python 设计模式:桥接模式
1. 什么是桥接模式? 桥接模式是一种结构型设计模式,它通过将抽象部分与其实现部分分离,使得两者可以独立变化。桥接模式的核心思想是将抽象和实现解耦,从而提高系统的灵活性和可扩展性。 桥接模式的核心思想是将一个类的接口与其…...
7.6 GitHub Sentinel后端API实战:FastAPI高效集成与性能优化全解析
GitHub Sentinel Agent 用户界面设计与实现:后端 API 集成 关键词:前后端分离架构、RESTful API 设计、数据序列化、命令行工具开发、集成测试 后端 API 集成关键技术实现 本阶段需要完成前端界面与后端服务的无缝对接,实现以下核心功能: #mermaid-svg-FFnzT13beWV52dtx …...
Smart AI:在AI浪潮中崛起的智能NFT生态革命者
技术引领,智能进化:Smart AI强势登场 在全球AI技术浪潮席卷之际,由澳大利亚顶尖技术团队倾力打造的Smart AI平台横空出世,以其革命性的NFT智能进化系统,正在彻底重塑数字资产的未来图景。Smart AI不仅是一个平台&…...
Linux——基于socket编程实现简单的Tcp通信
前言1:想要实现一个简单的Tcp通信不难,对于初学者而言,难点在于使用了大量未曾接触过的函数调用,所以本篇重点在于详解每部分代码中相关函数的功能。 1. 简单认识一下TCP传输 TCP通信协议是面向字节流的、可靠的、有连接的传输&a…...
STL C++详解——priority_queue的使用和模拟实现 堆的使用
priority_queue的使用 std::priority_queue 是 C 标准模板库(STL)中的一个容器适配器,提供了优先队列的功能。 优先队列:是一种特殊的队列,队列中的每个元素都有与之关联的优先级,优先级高的元素会先出队…...
是否可以使用非被动 S4P 文件进行反嵌?
AEDT 电路去嵌入算法使用假定线性时不变 (LTI) 行为的转换。如果非被动 S 参数块不是 LTI,则倒数函数将无法按预期工作。...
GAEA的技术优势:分层加密与去中心化数据治理
GAEA采用分层加密架构,将用户数据分为三个层级: 基础层(链上数据):用户身份哈希、资源贡献记录等核心数据通过零知识证明(ZK-SNARKs)进行链上加密,确保不可篡改和匿名性。 情感层…...
使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第九讲)
这一期讲解GUI_guider中的容器控件的使用以及相关函数,容器本质上是具有布局和自动调整大小功能的基本对象 ,通常用来装载其他子控件。 打开上一期的项目,在工具栏中选中容器控件拖拽到界面中,具体如图所示: 容器默认…...
SparkStreaming概述
SparkStreaming主要用于流式计算,处理实时数据。 DStream是SparkStreaming中的数据抽象模型,表示随着时间推移收到的数据序列。 SparkStreaming支持多种数据输入源(如Kafka、Flume、Twitter、TCP套接字等)和数据输出位置…...
LeetCode---整数反转
整数反转 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。 示例 示例 1: 输入:x 123 输出:321 示例 2…...
Conceptrol: Concept Control of Zero-shot Personalized Image Generation(个性化图像生成)
文章目录 一、论文介绍二、项目部署三、效果展示3.1ipadapter plus sd1.5的效果3.2ipadapter plus sd1.5 plus concept的效果3.3两者结果的比较:原本的ipadapter、加了concept的ipadapter 一、论文介绍 个性化图像生成中的平衡问题:现有的zero-shot adap…...
【Harmony】常用工具类封装
文章目录 一,简介二,网络请求工具类2.1、鸿蒙原生http封装2.2、第三方axios封装(需提前下载依赖) 三、录音笔相关工具类3.1、录音封装(录入)3.2、录音封装(放音/渲染)3.3、文件写入封装(针对录音/放音功能) 四、RDB关系型数据库4.1、relationalStore简答…...
大模型部署到本地就是私有化部署吗?
大模型私有化的定义需要从部署方式和数据/模型控制权两个维度来理解,不能简单地仅以“部署位置”或“数据训练”单一条件判断。以下是具体分析: 1. 大模型私有化的核心定义 根据知识库中的描述([1][2][3][8]): 私有化…...
C语言高频面试题——嵌入式系统中中断服务程序
在嵌入式系统中,中断服务程序(ISR)的设计需遵循严格的规则以确保系统稳定性和实时性。以下是对这段代码的分析及改进建议: 代码分析 __interrupt double compute_area (double radius) { double area PI * radius * radius; pri…...
JavaFX 实战:从零打造一个功能丰富的英文“刽子手”(Hangman)游戏
大家好!今天我们要挑战一个经典的单词猜谜游戏——“刽子手”(Hangman),并使用 JavaFX 这个强大的 GUI 工具包来赋予它现代化的交互体验。这个项目不仅有趣,而且是学习和实践 JavaFX 核心概念的绝佳途径,涵…...
第 2.1 节: 机器人仿真环境选择与配置 (Gazebo, MuJoCo, PyBullet)
在真实机器人硬件上进行开发和测试既耗时又存在风险(硬件损坏、安全问题)。机器人仿真环境提供了一个虚拟的沙盒,让开发者能够在计算机中模拟机器人的物理行为、传感器读数和环境互动,极大地加速了开发、测试和调试过程。特别是对…...
网络开发基础(游戏)之 粘包分包
粘(nin)包、分包 在网络通信中,TCP协议是面向流的协议,没有消息边界概念,粘包和分包是常见的问题。在某种情况下(例如网络环境不稳定)就会导致"粘包"和"分包"问题…...
联邦元学习实现个性化物联网的框架
随着数据安全和隐私保护相关法律法规的出台,需要直接在中央服务器上收集和处理数据的集中式解决方案,对于个性化物联网而言,训练各种特定领域场景的人工智能模型已变得不切实际。基于此,中山大学,南洋理工大学…...
使用 Nacos 的注意事项与最佳实践
📹 背景 Nacos 凭借其强大💪的服务发现、配置管理和服务管理能力,成为构建分布式系统的得力助手。然而,要充分发挥 Nacos 的优势,实现系统的高性能、高可用,掌握其使用过程中的注意事项和最佳实践至关…...
在Pytorch中使用Tensorboard可视化训练过程
【在Pytorch中使用Tensorboard可视化训练过程】 https://www.bilibili.com/video/BV1Qf4y1C7kz/?share_sourcecopy_web&vd_sourcef00bfb41b3b450c3767070ed82f30ac8 主要功能: 1.保存网络结构图 2.保存训练集的损失Loss,验证集的正确性Accuracy以…...
15.电感特性在EMC设计中的运用
电感特性在EMC设计中的运用 1. 共模电感与差模电感的差异2. 电感的高频等效特性3. 电感在EMC设计中的使用注意事项3.1 LC滤波计算3.2 并联型多级浪涌防护的电感退耦 1. 共模电感…...
代理设计模式:从底层原理到源代码 详解
代理设计模式(Proxy Pattern)是一种结构型设计模式,它通过创建一个代理对象来控制对目标对象的访问。代理对象充当客户端和目标对象之间的中介,允许在不修改目标对象的情况下添加额外的功能(如权限控制、日志记录、延迟…...
25、简述.NET程序集(Assembly)
.NET 程序集(Assembly) .NET 程序集(Assembly) 是 .NET 应用程序的基本部署单元,包含以下核心内容: 类型与代码: 存储类、接口等类型的定义及实现(以中间语言 IL 形式)。…...
JavaScript 笔记 --- part 5 --- Web API (part 3)
(webAPI part3) BOM 操作 JS 执行机制 javascript 是单线程的, 也就是说, 只能同时执行一个任务。 为了解决这个问题, 利用多核 CPU 的计算能力, HTML5 提出 Web Worker API, 允许 JavaScript 脚本创建多个线程, 并将任务分配给这些线程。 于是, JS 出现了同步和异步的概念。…...
HCIP(OSPF)(3)
OSPF 报文结构 公共头部:包含版本(8bit)、类型(8bit)、报文长度(16bit)、路由器 ID(32bit)、区域 ID(32bit)、校验和(16bit࿰…...
Docker:重塑应用开发与部署的未来[特殊字符]
Docker:重塑应用开发与部署的未来🚀 在数字化转型的浪潮中🌊,应用开发与部署面临着诸多挑战,如环境一致性差、资源利用率低、运维复杂等。而Docker,作为容器技术领域的明星产品🌟,凭…...
逻辑回归:损失和正则化技术的深入研究
逻辑回归:损失和正则化技术的深入研究 引言 逻辑回归是一种广泛应用于分类问题的统计模型,尤其在机器学习领域中占据着重要的地位。尽管其名称中包含"回归",但逻辑回归本质上是一种分类算法。它的核心思想是在线性回归的基础上添…...
如何改电脑网络ip地址完整教程
更改电脑的网络IP地址以满足特定的网络需求,本文将为您提供一份详细的步骤指南。其实,改变IP地址并不是一件复杂的事,能解决因为IP限制带来的麻烦。以下是操作指南: 方法一:Windows 系统,通过图形界面修改 …...
Scenario Dreamer:用于生成驾驶模拟环境的矢量化潜扩散模型
25年3月来自加拿大 Mila AI研究院、蒙特利尔大学、蒙特利尔理工、普林斯顿、加拿大 CIFAR AI Chair 计划和 Torc 机器人公司的论文“Scenario Dreamer: Vectorized Latent Diffusion for Generating Driving Simulation Environments”。 Scenario Dreamer,是一个完…...
# 基于PyTorch的食品图像分类系统:从训练到部署全流程指南
基于PyTorch的食品图像分类系统:从训练到部署全流程指南 本文将详细介绍如何使用PyTorch框架构建一个完整的食品图像分类系统,涵盖数据预处理、模型构建、训练优化以及模型保存与加载的全过程。 1. 系统概述 本系统实现了一个基于卷积神经网络(CNN)的…...
【MCP Node.js SDK 全栈进阶指南】初级篇(1):MCP开发环境搭建详解
引言 Model Context Protocol (MCP) 是一种开放标准,旨在规范模型与应用程序之间的交互方式。本文作为MCP TypeScript-SDK系列的第一篇,将详细介绍如何搭建MCP开发环境,包括Node.js与TypeScript环境配置、SDK安装、开发工具推荐以及项目结构设计,帮助你快速入门MCP应用开发…...
unity脚本-FBX自动化模型面数校验
根据目前模型资源平均面数预算进行脚本制作,自动化校验模型面数是否符合规范。 *注:文件格式为.cs。需要放置在unity资源文件夹Assets>Editor下。 测试效果(拖一个fbx文件进unity时自动检测): 以下为完整代码 us…...
压力容器的优化设计
1 优化设计概述 优化设计是一种寻找确定最优设计方案的技术。所谓“最优设计”,指的是一种方案可以满足所有的设计要求,而且所需的支出(如重量,面积,体积,应力,费用等)最小。也就是…...
在Windows上安装Git
一、安装 Git 下载 Git地址:Git - Downloads (git-scm.com) 1、在页面中找到适用于 Windows 系统的最新版本安装包(通常为.exe 格式文件),点击下载链接。 出于访问Git官网需要科学上网,不会的可以私信我要软件包&…...
python包管理器,conda和uv 的区别
python包管理器,conda和uv 的区别 以下是 conda 和 uv 在 Python 包管理中的深度对比,结合知识库内容进行分析: 1. 核心设计理念 conda 以“环境为中心”,强调跨语言支持(如 Python、R、Julia)和严格的依赖…...
Oracle在ERP市场击败SAP
2024年,甲骨文(Oracle)以87亿美元的ERP收入和6.63%的市场份额,首次超越SAP,成为全球最大的ERP应用软件供应商,结束了SAP自上世纪80年代以来在该领域的长期霸主地位。据APPS RUN THE WORLD的市场调研&#x…...
Kafka 消息积压监控和报警配置的详细步骤
Kafka 消息积压监控和报警配置的详细步骤示例,涵盖常用工具(如 Prometheus Grafana、云服务监控)和自定义脚本方法: 一、监控配置 方法1:使用 Prometheus Grafana kafka-exporter 步骤1:部署 kafka-ex…...
记录一次使用面向对象的C语言封装步进电机驱动
简介 (2025/4/21) 本库对目前仅针对TB6600驱动下的42步进电机的基础功能进行了一定的封装, 也是我初次尝试以面向对象的思想去编写嵌入式代码, 和直流电机的驱动步骤相似在调用stepmotor_attach()函数和stepmotor_init()函数之后仅通过结构体数组stepm然后指定枚举变量中的id即…...
QTextDocument 入门
一、QTextDocument QTextDocument 是 Qt 中用于处理富文本文档的核心类,支持文本格式、图片、表格等复杂内容。 1. QTextDocument 入门 1.1 基本概念 QTextDocument 是 Qt 中用于处理富文本内容的核心类,它提供了: 结构化文本存储(段落、列表、表格等) 文本格式支持(…...
Arthas进阶用法
目录 查看已加载的类反编译代码动态执行代码排查 HTTP 请求问题热更新代码获取 Spring Context 并操作查看 JVM 信息自定义命令Web Console重置与退出 查看已加载的类 sc 命令 :可以查找所有 JVM 已经加载到的类。如果搜索的是接口,还会搜索所有的实现类…...
三生原理与现有密码学的核心区别?
AI辅助创作: 三生原理与现有密码学的核心区别 一、哲学基础与设计逻辑 动态生成 vs 静态分析 三生原理以“阴阳动态平衡”为核心,通过参数化生成(如素数构造中的阴阳元联动公式)模拟系统演化过程,而现有密码…...
定义python中的函数和类
1.函数 在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回 1.1 定义函数 def showshow(sex):if sex1:return manelse:retu…...
明远智睿2351开发板四核1.4G Linux处理器:驱动创新的引擎
在科技日新月异的今天,创新成为了推动社会进步的核心动力。而在这场创新的浪潮中,一款性能卓越、功能全面的处理器无疑是不可或缺的引擎。今天,我们介绍的这款四核1.4G处理器搭配Linux系统的组合,正是这样一款能够驱动未来创新的强…...
【前端】【业务逻辑】【面试】JSONP处理跨域原理与封装
🧠 一、JSONP 是什么? 项目内容📌 全称JSON with Padding📍 用途跨域请求数据的一种方式,绕过同源策略📦 本质通过 <script> 标签加载远程 JS 文件,这个文件执行一个回调函数并传入数据 …...
深入探索RAG:用LlamaIndex为大语言模型扩展知识,实现智能检索增强生成
大型语言模型(LLM),如ChatGPT和Llama,在回答问题方面表现出色,但它们的知识仅限于训练时所获取的信息。它们无法访问私有数据,也无法在训练截止日期之后学习新知识。那么,核心问题就是……我们如…...