首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Java框架快速入门: Spring Security+OAuth2之搭建授权服务器——JWKS端点与RSA密钥对
📅 2026/9/15 6:47:17
✍️ 爱科研究院
👁 阅读 3,247
纲要核心概念JWKS(JSON Web Key Set)用于暴露公钥的标准端点资源服务器通过该端点获取验证JWT所需的公钥非对称加密 (RSA)授权服务器使用私钥签名JWT资源服务器使用公钥验签AuthorizationServerSecurityConfigurationSpring Security OAuth2 提供的授权服务器安全配置基类KeyPairJDK 中的密钥对封装包含公钥与私钥keytoolJDK 自带的密钥与证书管理工具用于生成.jks密钥库文件核心流程使用keytool生成RSA密钥对保存为keystore.jks文件通过配置类读取.jks将KeyPair暴露为Bean创建JWKSet端点将公钥转换为标准JWK格式并返回配置安全策略允许公开访问/.well-known/jwks.json涉及代码与配置KeyPairConfig加载密钥库创建KeyPair实例JwkSetEndpointFrameworkEndpoint控制器返回JWKSetJSONJwkSetEndpointConfiguration继承AuthorizationServerSecurityConfiguration放行JWKS路径keytool命令为什么需要 JWKS 端点在资源服务器与授权服务器分离的架构中资源服务器需要验证JWT的签名。若使用非对称加密授权服务器持有私钥进行签名资源服务器则必须获取对应的公钥才能完成验签。Spring Security 5.1 之后资源服务器对JWT的支持默认仅接受通过jwk-set-uri配置的公钥来源不再支持直接内嵌对称密钥或原始公钥。因此授权服务器必须提供一个标准的JWKS端点供资源服务器动态获取公钥。JWKS(JSON Web Key Set) 实际上就是一个JSON文档通常放置在/.well-known/jwks.json其结构如下{keys:[{kty:RSA,e:AQAB,n:0vx7a...,alg:RS256}]}资源服务器在启动时向该端点发起请求拿到公钥集合后即可用于验证JWT无需在每台资源服务器上硬编码公钥。项目结构在原有授权服务器项目的基础上新增以下几个类src/main/java/com/example/auth/ ├── config/ │ ├── KeyPairConfig.java │ └── JwkSetEndpointConfiguration.java └── endpoint/ └── JwkSetEndpoint.java src/main/resources/ └── keystore.jks生成 RSA 密钥对JDK 自带的keytool工具可以方便地生成密钥库文件。在命令行中执行以下命令Windows 系统需将换行符\去掉合并为一行keytool-genkeypair\-aliasmy-auth-key\-keyalgRSA\-keypasskeypass123\-keystorekeystore.jks\-storepassstorepass123\-validity3650参数说明参数说明-genkeypair生成密钥对-alias别名后续通过别名从密钥库中获取密钥对-keyalg密钥算法这里指定为RSA-keypass密钥密码-keystore密钥库文件名执行后生成keystore.jks-storepass密钥库密码-validity有效期(天)执行成功后将生成的keystore.jks放入src/main/resources目录下。加载密钥对KeyPairConfig为了让JWKS端点能够获取公钥需要先将密钥库中的KeyPair加载到 Spring 容器中。packagecom.example.auth.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.io.ClassPathResource;importjava.security.KeyPair;importjava.security.KeyStore;ConfigurationpublicclassKeyPairConfig{BeanpublicKeyPairkeyPair()throwsException{// 加载 classpath 下的密钥库文件ClassPathResourceksFilenewClassPathResource(keystore.jks);// 创建 KeyStore 工厂实例KeyStorekeyStoreKeyStore.getInstance(JKS);// 需要传入密钥库文件和密码keyStore.load(ksFile.getInputStream(),storepass123.toCharArray());// 通过别名和密钥密码获取 KeyPairjava.security.KeyStore.PasswordProtectionkeyPasswordnewjava.security.KeyStore.PasswordProtection(keypass123.toCharArray());java.security.KeyStore.PrivateKeyEntryentry(java.security.KeyStore.PrivateKeyEntry)keyStore.getEntry(my-auth-key,keyPassword);// 从条目中拿到证书的公钥和私钥构造 KeyPairjava.security.PublicKeypublicKeyentry.getCertificate().getPublicKey();java.security.PrivateKeyprivateKeyentry.getPrivateKey();returnnewKeyPair(publicKey,privateKey);}}要点说明ClassPathResource定位资源文件。通过KeyStore加载.jksstorepass与keypass必须与生成时一致。使用别名my-auth-key获取条目后分别提取公钥和私钥组装成java.security.KeyPair。实现 JWKS 端点JwkSetEndpoint该端点负责将KeyPair中的公钥转换为标准JWK格式并返回。这里使用FrameworkEndpoint注解表明这是一个框架级别的端点与常规RestController作用相同但语义更清晰。packagecom.example.auth.endpoint;importcom.nimbusds.jose.jwk.JWKSet;importcom.nimbusds.jose.jwk.RSAKey;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.security.oauth2.provider.endpoint.FrameworkEndpoint;importjava.security.KeyPair;importjava.security.interfaces.RSAPublicKey;importjava.util.Map;FrameworkEndpointpublicclassJwkSetEndpoint{privatefinalKeyPairkeyPair;AutowiredpublicJwkSetEndpoint(KeyPairkeyPair){this.keyPairkeyPair;}GetMapping(/.well-known/jwks.json)ResponseBodypublicMapString,ObjectgetKey(){// 从 KeyPair 中提取 RSA 公钥RSAPublicKeypublicKey(RSAPublicKey)this.keyPair.getPublic();// 使用 Nimbus JOSEJWT 提供的构建器生成 RSAKeyRSAKeyrsaKeynewRSAKey.Builder(publicKey).build();// 构建 JWKSet 并转为 JSON MapreturnnewJWKSet(rsaKey).toJSONObject();}}代码中使用了nimbus-jose-jwt库确保pom.xml中包含以下依赖若已集成 Spring Security OAuth2 则通常已传递引入dependencygroupIdcom.nimbusds/groupIdartifactIdnimbus-jose-jwt/artifactIdversion9.37.3/version/dependency端点访问时会将RSAPublicKey封装为JWK对象并输出类似下文的JSON{keys:[{kty:RSA,e:AQAB,n:5vC2a...,alg:RS256}]}配置安全策略JwkSetEndpointConfiguration授权服务器本身也是一个Spring Security应用/.well-known/jwks.json需要被公开访问不能被默认的表单登录或 HTTP Basic 拦截。需要继承AuthorizationServerSecurityConfiguration并专门针对该路径放行。packagecom.example.auth.config;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.annotation.Order;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerSecurityConfiguration;ConfigurationOrder(1)publicclassJwkSetEndpointConfigurationextendsAuthorizationServerSecurityConfiguration{Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{http.requestMatchers().antMatchers(/.well-known/jwks.json).and().authorizeRequests().antMatchers(/.well-known/jwks.json).permitAll();}}重要细节使用Order(1)确保该配置优先级最高优先于其他安全配置。通过requestMatchers().antMatchers(...)限定该配置仅作用于JWKS路径避免与其他授权端点冲突。permitAll()表示无需认证即可访问符合公钥公开的需求。整体流程KeyStore授权服务器资源服务器KeyStore授权服务器资源服务器启动时加载 keystore.jks生成 KeyPair BeanGET /.well-known/jwks.json从 KeyPair 提取 RSAPublicKey构建 JWKSet200 OK {keys:[...]}缓存公钥用于后续 JWT 验签验证端点启动授权服务器后访问http://localhost:8080/.well-known/jwks.json应返回公钥的JWK描述。此时资源服务器即可通过spring.security.oauth2.resourceserver.jwt.jwk-set-uri指向该地址实现自动公钥获取。补充说明AuthorizationServerSecurityConfiguration当前在spring-security-oauth2中标记为Deprecated因为 Spring 官方正在开发新的授权服务器spring-authorization-server。但在新项目成熟前生产环境依然以此方案为主划线仅表示未来可能变动不影响当前使用。keytool生成的.jks文件包含私钥严禁对外暴露只应在授权服务器内部使用。实际部署时应将storepass和keypass通过环境变量或配置中心注入而不是硬编码在代码中。总结本文介绍了在 Spring Security OAuth2 授权服务器中暴露JWKS端点的完整流程通过keytool生成RSA密钥对 → 使用KeyPairConfig加载KeyPair→ 创建JwkSetEndpoint输出标准JWKS→ 配置JwkSetEndpointConfiguration放行路径。整个过程实现了公钥的动态分发使资源服务器能够安全、独立地验证JWT。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/15 6:47:17
从010 Editor到Header Editor:各类编辑器工具的选择与应用
2026/9/15 6:47:17
冰岛大学云计算和大数据笔记(二)
2026/9/15 6:47:17
Java框架快速入门: Spring Security+OAuth2之搭建授权服务器(依赖与表结构)
2026/9/15 7:42:20
滑动窗口最大值优化:单调队列如何把O(nk)降到O(n)
2026/9/15 7:42:20
15 (S)-Hete-biotin标记技术:原理、优势与应用
2026/9/15 7:42:20
MATLAB双流体两相流计算模型:面向工艺工程师的管道压降与流型分析工具
2026/9/15 7:42:20
安全运营检测实验室搭建实战:从攻击模拟到规则验证
2026/9/15 7:42:20
Java文件操作安全:防御路径遍历攻击实践
2026/9/15 7:37:20
AI算力爆发下的液冷技术解决方案与实战经验
2026/9/15 0:01:49
2026年NVMe SSD装机避坑指南:PCIe 4.0/5.0、NVMe启动与M.2 Key兼容性实测
2026/9/15 0:01:49
Flutter与OpenHarmony物理动画实现指南
2026/9/15 0:01:49
vscode插件开发之语言服务器,这次让用 TaoToken 接入的 Codex 排查 LSP 服务端连接
2026/9/14 7:37:16
拯救者Y7000黑屏故障排查与维修实战指南
2026/9/14 2:50:57
AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
2026/9/14 11:25:37
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化