尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
微服务中使用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两者是独立的认证体系。
RELATED

相关推荐

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

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

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

📅 2026/9/23 15:35:44
YOLOX 自定义目标检测训练实战:VOC 数据、训练评估与预测展示

YOLOX 自定义目标检测训练实战:VOC 数据、训练评估与预测展示

YOLOX 自定义目标检测训练实战:VOC 数据、训练评估与预测展示 这篇教程根据我复现 YOLOX 目标检测流程时整理,重点演示依赖安装、VOC 数据接入、类别配置、训练评估和单图预测可视化。 本文整理自我的学习和项目复现过程,尽量按实操顺序保留…

📅 2026/9/23 15:34:43
Java 继承②

Java 继承②

目录1. super 关键字2. super 和 this3. this和super访问时的内存布局1. super 关键字 在父类成员变量和子类成员变量名字相同的情况下,为了在子类中访问父类的成员。 super关键字的用法 : super.父类成员变量 class Person{String name;int age 10;public void …

📅 2026/9/12 3:18:38
MORE NEWS

更多资讯

📰

PandaMH源码解析:内存读取与SDL覆盖层构建全图调试工具

简介:这份PandaMH源码资源围绕魔兽争霸III地图编辑器中的全图功能展开,面向地图制作者、游戏模组开发者和有一定编程基础的学习者。源码基于C#编写,包含Visual Studio解决方案与多个核心模块,可用于理解全图视野实现、游戏事件处理…

📰

Cache模拟器实战指南:从地址映射到命中率调优

简介:缓存(Cache)是提升计算机系统性能的关键机制,其核心目标是通过暂时存放高频访问数据来降低处理器访问主存的延迟;这份资源是一套VS2010环境下编写的Cache模拟器源码,面向计算机体系结构学习者、备考者…

📰

qq三国新手礼包解析:转行避坑最佳实践

qq三国新手礼包解析:转行避坑最佳实践 面对一长串红色的 StackTrace,你是不是也头大如斗?别慌,这不仅是代码报错,更是你技术底层的照妖镜。在转行面试中,这种“报错一堆看不懂”的场景,恰恰是考察候选人排查能力与最佳实践的黄金机会。今…

📰

内网时间同步必读:NTP与SNTP原理、chrony配置与避坑指南

简介:NTP/SNTP时钟协议原理PPT课件,面向网络工程师、运维人员及计算机网络学习者,系统讲解NTP/SNTP的发展背景、分层时钟模型与时间同步机制。NTP由David L. Mills教授于1985年提出,基于UDP 123端口交换时间戳,通过T1~…

📰

Word空白页删不掉?5个最佳实践彻底解决

Word空白页删不掉?5个最佳实践彻底解决 面对一堆报错日志和看不懂的 StackTrace,你是不是也感到头疼?别急,咱们今天不聊虚的,直接上手。 在自动化文档处理脚本中,Word…

📰

Pelican 静态页面(Pages)Markdown 编写指南:从最小示例到源码解析

【免费下载链接】pelican Static site generator that supports Markdown and reST syntax. Powered by Python. 项目地址: https://gitcode.com/gh_mirrors/pe/pelican 点击查看 免费下载 导读 本指南以仓库测试夹具 page_markdown.md 为标本,系统讲解…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬