微服务中使用JWT 认证体系详解:HMAC vs RSA 签名、OAuth2 Token 获取机制
微服务中使用JWT 认证体系详解HMAC vs RSA 签名、OAuth2 Token 获取机制一、JWT 基础概念1.1 什么是 JWTJWTJSON Web Token是一种紧凑的、自包含的令牌格式用于在各方之间安全传递信息。它由三部分组成用点号.分隔xxxxx.yyyyy.zzzzz ↓ ↓ ↓ Header Payload SignatureHeader声明令牌类型和签名算法Payload存放实际数据用户ID、权限、过期时间等Signature对前两部分的签名防止数据被篡改1.2 一个 JWT 长什么样eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0IiwiZXhwIjoxNzg0Njc4NDA1fQ.签名部分对 Header 进行 Base64 解码{alg:RS256,// 签名算法typ:JWT// 令牌类型}对 Payload 进行 Base64 解码{user_name:test,member_id:100000,exp:1784678405,// 过期时间Unix 时间戳client_id:my_app,scope:[read,write]}注意Header 和 Payload 只是 Base64 编码不是加密任何人都能解码看到内容。Signature 才是保证数据不被篡改的关键。注博客https://blog.csdn.net/badao_liumang_qizhi二、两种签名算法对比HMAC vs RSA2.1 HMAC对称加密签名代表算法HS256、HS384、HS512原理用一个共享密钥Secret Key对数据进行签名和验签签名方和验签方使用同一个密钥。签名过程HMAC-SHA256(Header . Payload, 密钥) → Signature 验签过程用同一个密钥重新计算签名对比是否一致特点签名和验证都用同一把钥匙速度快、实现简单适合单体系统或前端-后端之间的简单场景密钥泄露 既能伪造又能验证典型场景前端登录后后端用一个 Secret 签发 Token前端携带该 Token 访问同一后端。┌──────────┐ 同一把密钥 ┌──────────┐ │ 登录服务 │ ←────────────────────→ │ 业务服务 │ │ (签发方) │ 签发 验证都用它 │ (验证方) │ └──────────┘ └──────────┘2.2 RSA非对称加密签名代表算法RS256、RS384、RS512原理使用一对公钥-私钥。私钥签名公钥验签。签名方和验签方使用不同的密钥。签名过程RSA-SHA256(Header . Payload, 私钥) → Signature 验签过程用公钥验证签名是否与数据匹配特点私钥签名只有认证服务有公钥验签所有业务服务都可以有公钥泄露无所谓只能验证不能伪造适合分布式微服务架构计算稍慢典型场景独立的认证服务用私钥签发 Token各个微服务用公钥验证 Token 的合法性。┌──────────────┐ │ 认证服务 │ 持有私钥负责签发 Token │ (Auth Server)│ └──────┬───────┘ │ 签发的 Token ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 服务 A │ │ 服务 B │ │ 服务 C │ │ 持有公钥 │ │ 持有公钥 │ │ 持有公钥 │ │ 只能验证 │ │ 只能验证 │ │ 只能验证 │ └──────────┘ └──────────┘ └──────────┘2.3 核心区别一览维度HMAC (HS256)RSA (RS256)密钥一个共享密钥一对公私钥签发持有密钥的任何人只有持有私钥的一方验证持有密钥的任何人持有公钥的任何人安全性密钥泄露 全部完蛋公钥公开也安全性能快稍慢适用场景单体/简单前后端微服务/多系统密钥管理所有需验证的服务都要密钥只有认证服务有私钥三、为什么微服务架构用 RSA 而不是 HMAC假设你有 20 个微服务都需要验证 Token如果用 HMAC每个服务都要存储同一个密钥任何一个服务泄露密钥攻击者就能伪造 Token密钥轮换时要同时更新 20 个服务如果用 RSA只有认证服务有私钥其他 20 个服务只有公钥泄露了也只能验证不能伪造私钥轮换只改认证服务一处这就是为什么项目使用独立的认证服务 RSA 公钥的架构。四、OAuth2 协议基础4.1 OAuth2 是什么OAuth2 是一套授权框架定义了客户端如何获取访问令牌Access Token。它不关心 Token 的具体格式但通常与 JWT 配合使用。4.2 四种授权模式模式适用场景简述Authorization CodeWeb应用、第三方登录最安全需要浏览器跳转Password Grant内部系统、受信任客户端直接传账号密码换 TokenClient Credentials服务间调用无用户参与纯机器对机器Implicit已废弃不推荐使用4.3 Password Grant 详解客户端(ApiPost/curl) 认证服务(Auth Server) │ │ │ POST /oauth/token │ │ Authorization: Basic base64(id:pw)│ │ Body: grant_typepassword │ │ usernamexxx │ │ passwordxxx │ │──────────────────────────────────→ │ │ │ 验证账号密码 │ │ 用私钥签发 JWT │ { │ │ access_token: eyJ..., │ │ token_type: bearer, │ │ expires_in: 53640, │ │ refresh_token: eyJ... │ │ } │ │←────────────────────────────────── │ │ │请求中的两层认证Basic AuthAuthorization: Basic xxx证明你是哪个客户端应用将client_id:client_password进行 Base64 编码例如demo_app:123456→ZGVtb19hcHA6MTIzNDU2表示我是 demo_app 这个应用Body 中的账号密码证明你代表哪个用户usernamepassword表示我代表 zhangsan 这个用户请求授权4.4 返回结果字段说明{access_token:eyJhbGciOiJSUzI1NiIs...,// 访问令牌调接口时用token_type:bearer,// 令牌类型固定为 bearerrefresh_token:eyJhbGciOiJSUzI1NiIs...,// 刷新令牌用于续期expires_in:53640,// access_token 有效期秒scope:read write,// 授权范围user_name:zhangsan,// 用户名member_id:100000// 业务字段}五、两种 Token 的本质区别以实际场景说明为什么前端登录拿到的 Token不能用于调用微服务接口5.1 前端 Web TokenHMAC 签名浏览器 → 前端登录接口(/open/login) → 返回 coc_jwt放在 Set-Cookie 中签名算法HS512HMAC签发方前端网关/BFF 层验证方同一个前端网关用途标识浏览器会话前端页面鉴权特征密钥只在网关内部微服务拿不到这个密钥5.2 微服务 TokenRSA 签名客户端 → 认证服务(/oauth/token) → 返回 access_tokenJWTRS256 签名签名算法RS256RSA签发方专用认证服务用私钥签名验证方所有微服务用公钥验签用途服务间调用鉴权特征每个微服务配置公钥即可独立验证5.3 为什么不能混用前端 Token (HS512) → 微服务 (配置的是 RSA 公钥) ↓ 尝试用 RSA 公钥验证 HMAC 签名 ↓ ❌ Cannot convert access token to JSON微服务只认识 RSA 签名的 Token。你拿 HMAC 签名的 Token 给它它用 RSA 公钥去验签格式完全对不上所以报错。六、完整认证架构图┌─────────────────────────────┐ │ 认证服务 (Auth Server) │ │ 持有 RSA 私钥 │ │ /oauth/token │ │ 签发 RS256 JWT │ └──────────┬──────────────────┘ │ ┌────────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ A 服务 │ │ B 服务 │ │ C 服务 │ │ 端口 3012 │ │ 端口 3013 │ │ 端口 3014 │ │ 配置 RSA 公钥│ │ 配置 RSA 公钥│ │ 配置 RSA 公钥│ │ 独立验签 │ │ 独立验签 │ │ 独立验签 │ └──────────────┘ └──────────────┘ └──────────────┘ ┌─────────────────────────────────────────────────┐ │ 前端网关 (BFF / Gateway) │ │ /open/login → 签发 coc_jwt (HS512) │ │ 用于浏览器 Cookie 会话管理 │ │ 与微服务 Token 体系完全独立 │ └─────────────────────────────────────────────────┘七、通用代码示例7.1 Java Spring Boot 配置 RSA 公钥验签# application.ymlsecurity:jwt:signing-key:|-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... -----END PUBLIC KEY-----resource-ids:my-servicematchers:-path:/api/public/**attribute:permitAll-path:/api/**attribute:authenticated7.2 curl 获取 OAuth2 Token# 将 client_id:client_password 进行 Base64 编码后放入 Basic Authcurl-s-XPOSThttps://auth-server.com/oauth/token\-HContent-Type: application/x-www-form-urlencoded\-umy_client_id:my_client_password\-dgrant_typepasswordusernameuserpasswordpass-u参数等价于-HAuthorization: Basic$(echo-nmy_client_id:my_client_password|base64)7.3 PowerShell 获取 Token# 构造 Basic Auth$pairmy_client_id:my_client_password$base64[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($pair))# 请求 Token$headers {AuthorizationBasic$base64Content-Typeapplication/x-www-form-urlencoded}$bodygrant_typepasswordusernameuserpasswordpass$responseInvoke-WebRequest-Urihttps://auth-server.com/oauth/token-Method POST-Headers$headers-Body$body-UseBasicParsing$token($response.Content|ConvertFrom-Json).access_token7.4 Java 代码获取 TokenRestTemplate/** * 通过 OAuth2 Password Grant 获取访问令牌 */publicStringgetAccessToken(){StringclientIdmy_client_id;StringclientPasswordmy_client_password;StringcredentialsBase64.getEncoder().encodeToString((clientId:clientPassword).getBytes());HttpHeadersheadersnewHttpHeaders();headers.set(Authorization,Basic credentials);headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);MultiValueMapString,StringbodynewLinkedMultiValueMap();body.add(grant_type,password);body.add(username,user);body.add(password,pass);HttpEntityMultiValueMapString,StringrequestnewHttpEntity(body,headers);ResponseEntityMapresponserestTemplate.postForEntity(https://auth-server.com/oauth/token,request,Map.class);return(String)response.getBody().get(access_token);}7.5 使用 Token 调用业务接口# 获取到 token 后curl-s-XPOSThttp://127.0.0.1:8080/api/your-endpoint\-HAuthorization: Bearer eyJhbGciOiJSUzI1NiIs...\-HContent-Type: application/json\-d{pageNum:1,pageSize:10}八、验签过程详解当业务服务收到请求时1. 从 Header 中提取: Authorization: Bearer eyJxxx.eyJyyy.zzz 2. 拆分 JWT 三段: - Header: eyJxxx → 解码得 {alg:RS256,typ:JWT} - Payload: eyJyyy → 解码得 {user_name:test,exp:1784678405,...} - Signature: zzz 3. 用配置的 RSA 公钥验证签名: RSA_Verify(公钥, eyJxxx.eyJyyy, zzz) → true/false 4. 如果签名验证通过: - 检查 exp 是否过期 - 检查 resource-ids 是否匹配 - 提取用户信息注入到 SecurityContext 5. 如果验证失败: - 返回 401 Unauthorized - 错误信息如 Cannot convert access token to JSON格式不对 - 或 Access token expired过期九、总结概念一句话解释JWT一种自包含的令牌格式三段式结构HMAC (HS256/512)对称签名一把钥匙既签又验RSA (RS256)非对称签名私钥签、公钥验OAuth2一套获取令牌的标准流程/协议Password GrantOAuth2 的一种模式直接用账号密码换 TokenBasic Auth用 Base64(id:password) 标识客户端身份Bearer TokenToken 的传递方式放在 Authorization Header 中公钥公开的只能验证签名不能伪造私钥保密的用来签名只有认证服务持有核心理解在微服务架构中认证服务是唯一持有私钥的发证机关各个业务服务通过公钥验证证件的真伪而不需要每个服务都能发证。前端页面用的是另一套简单的会话机制HMAC Cookie两者是独立的认证体系。

相关新闻

DolphinX 实测:当 AI Agent 真正读懂你的时序数据,事情开始变得不一样

DolphinX 实测:当 AI Agent 真正读懂你的时序数据,事情开始变得不一样

DolphinX 实测:当 AI Agent 真正读懂你的时序数据,事情开始变得不一样 "DolphinDB 有了自己的 AI Agent 平台?"这是我看完 DolphinX 资料后的第一反应。坦白说,在 2026 年这个时间点,“数据库 AI” 已经算不…

2026/7/23 0:50:39阅读更多 →
北京市专精特新中小企业认定常见问题解答

北京市专精特新中小企业认定常见问题解答

一、已获得科技和创新型中小企业称号,截至上年末从事特定细分市场时间达3年以上,如何理解?答:申请企业需为有效期内的创新型中小企业或科技型中小企业,两者满足其一。细分市场判断的时间是截至上年末(即202…

2026/7/23 0:50:39阅读更多 →
珠海市关于广东省工程技术研究中心的奖补政策是怎样的?各区有多少补贴?

珠海市关于广东省工程技术研究中心的奖补政策是怎样的?各区有多少补贴?

一、珠海市(市级)奖补政策根据《珠海市科技创新平台建设管理办法》(珠科创〔2023〕109号)等政策,珠海市对科技创新平台(含工程技术研究中心)的奖补标准如下:省级奖励:对初…

2026/7/23 0:50:39阅读更多 →
TMS570 Flash API编程与ECC管理实战指南

TMS570 Flash API编程与ECC管理实战指南

1. 项目概述:TMS570 Flash API编程与ECC管理实战在汽车电子、工业控制这些对可靠性要求极高的领域,微控制器内部的Flash存储器扮演着核心角色。它不仅要安全地存储启动代码和应用程序,还得在严苛的电磁环境和温度变化下,保证十几年…

2026/7/23 2:02:49阅读更多 →
扫码登录的实现原理

扫码登录的实现原理

是所有大厂通用的三端交互标准时序图,逻辑完全一致: image 核心技术关键点 🔑 这部分是面试官打分的核心,必须精准命中: 二维码的本质 ❌ 绝对不能存储用户 ID、手机号等敏感信息 ✅ 仅存储一个全局唯一、随机不可预测…

2026/7/23 2:02:49阅读更多 →
第八章WSaiOS 事件感知引擎实现

第八章WSaiOS 事件感知引擎实现

第八章WSaiOS 事件感知引擎实现WSaiOS Event Perception Engine——从状态变化到事件理解作者:东塬一老翁技术支持:渭南市临渭区多模态智能技术研发工作室8.1 事件感知提出在 WSaiOS 世界理解体系中:世界元素解决:世界中有什么。世…

2026/7/23 2:02:49阅读更多 →
TM4C1294 I2C高速模式与FIFO/DMA配置实战指南

TM4C1294 I2C高速模式与FIFO/DMA配置实战指南

1. 项目概述在嵌入式开发中,I2C总线因其简洁的两线制(SDA和SCL)和灵活的软件寻址,成为了连接各类低速外设(如传感器、EEPROM、实时时钟等)的首选方案。然而,随着应用复杂度的提升,尤…

2026/7/23 2:02:49阅读更多 →
Tiva™ TM4C129 EPI接口深度解析:从寄存器配置到高速外设连接实战

Tiva™ TM4C129 EPI接口深度解析:从寄存器配置到高速外设连接实战

1. 项目概述与EPI接口核心价值在嵌入式系统开发中,尤其是涉及图像处理、高速数据采集或需要大容量缓存的场景,微控制器(MCU)自身的存储资源往往捉襟见肘。这时,外部存储器(如SDRAM、SRAM)或专用…

2026/7/23 2:02:49阅读更多 →
KingbaseES集群failover失败案例分析与解决方案

KingbaseES集群failover失败案例分析与解决方案

1. 案例背景与问题描述最近在维护一套KingbaseES V8R3数据库集群时,遇到了一次典型的failover切换失败案例。这套集群采用标准的主备架构,主库运行在node209(192.168.103.209),备库在node210(192.168.103.2…

2026/7/23 2:00:49阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/22 18:55:50阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/22 18:55:50阅读更多 →