微服务中使用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两者是独立的认证体系。

相关新闻

【ADMM】多主体综合能源系统+分布式ADMM研究(Matlab代码实现)

【ADMM】多主体综合能源系统+分布式ADMM研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

2026/8/23 13:47:20 阅读更多 →
MCP为什么正在成为Agent的“USB接口”?开发者先搞懂这4点

MCP为什么正在成为Agent的“USB接口”?开发者先搞懂这4点

摘要: MCP是一套让AI Agent连接外部数据和工具的统一标准。本文从统一连接、能力发现、上下文复用和安全边界4个方面,讲清它为什么被称为Agent的“USB接口”。以前开发AI Agent,如果要接入文件、数据库、GitHub或企业系统,通常要分…

2026/8/22 15:29:06 阅读更多 →
DolphinX 实测:当 AI Agent 真正读懂你的时序数据,事情开始变得不一样

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

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

2026/8/17 19:18:06 阅读更多 →

最新新闻

d2s-editor 暗黑2存档编辑器:免安装本地跑起来,3分钟改属性、导装备、修进度

d2s-editor 暗黑2存档编辑器:免安装本地跑起来,3分钟改属性、导装备、修进度

d2s-editor 暗黑2存档编辑器:免安装本地跑起来,3分钟改属性、导装备、修进度 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor d2s-editor 是一款免费开源的暗黑2存档编辑器,完全在浏览器里运行…

2026/8/27 4:11:19 阅读更多 →
C语言处理87万行CSV数据的工业级实战指南

C语言处理87万行CSV数据的工业级实战指南

1. 这不是“写个程序跑个数据”——87万条记录背后的真实战场你看到标题里那个“【C语言】2023年数学建模国赛C题87万条数据处理(附源码)”,第一反应可能是:不就是读个文件、算个平均值、排个序?顶多加个哈希表&#x…

2026/8/27 4:11:19 阅读更多 →
数据包络分析(DEA)核心原理与实战:从CCR/BCC模型到效率评估全流程

数据包络分析(DEA)核心原理与实战:从CCR/BCC模型到效率评估全流程

1. 项目概述:数据包络分析(DEA)是什么,以及我们为什么需要它在科研、管理或者项目评估的日常工作中,我们常常会遇到一个看似简单实则棘手的问题:如何公平、客观地评价一组具有多个投入和多个产出的决策单元…

2026/8/27 4:11:19 阅读更多 →
FakeLocation按应用单独虚拟定位完整指南

FakeLocation按应用单独虚拟定位完整指南

FakeLocation按应用单独虚拟定位完整指南 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 系统模拟位置开关是关的,状态栏也没有任何提示,但你照样能让某个…

2026/8/27 4:11:18 阅读更多 →
网盘下载只有 300KB/s 怎么办?3 步拿到真实下载地址的直链解析脚本

网盘下载只有 300KB/s 怎么办?3 步拿到真实下载地址的直链解析脚本

网盘下载只有 300KB/s 怎么办?3 步拿到真实下载地址的直链解析脚本 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动…

2026/8/27 4:11:18 阅读更多 →
层次分析法(AHP):从主观判断到量化决策的完整指南

层次分析法(AHP):从主观判断到量化决策的完整指南

1. 项目概述:从拍脑袋到结构化决策 做项目、选方案、评绩效,甚至生活中挑手机、选学校,我们每天都在做决策。但很多时候,所谓的“决策”不过是凭感觉、拍脑袋,或者陷入“公说公有理,婆说婆有理”的扯皮僵局…

2026/8/27 4:10:17 阅读更多 →

日新闻

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

2026/8/27 0:00:51 阅读更多 →
网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷云盘 / 夸…

2026/8/27 1:06:27 阅读更多 →
从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 Arduino ESP32 是乐鑫官方的 ESP32 系列 Ardui…

2026/8/27 1:06:27 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/26 14:45:33 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/26 17:46:43 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/26 14:46:37 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/26 3:50:20 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/26 17:46:39 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/26 1:24:05 阅读更多 →