OAuth 2.0 与 JWT 认证授权详解

举报
yd_212140359 发表于 2026/10/25 21:38:41 2026/10/25
【摘要】 OAuth 2.0 与 JWT 认证授权详解本文深入剖析 OAuth 2.0 授权框架与 JWT 令牌机制,帮助你设计安全可靠的认证授权体系。 认证 vs 授权┌─────────────────────────────────────────────────────────┐│ 认证(Authentication):你是谁? —— 验证身份 ││ 授权(Aut...

OAuth 2.0 与 JWT 认证授权详解

本文深入剖析 OAuth 2.0 授权框架与 JWT 令牌机制,帮助你设计安全可靠的认证授权体系。

认证 vs 授权

┌─────────────────────────────────────────────────────────┐
│  认证(Authentication):你是谁?  —— 验证身份            │
│  授权(Authorization):你能做什么?—— 验证权限          │
│                                                         │
│  OAuth 2.0 = 授权框架(解决"第三方访问资源")            │
│  OIDC      = 认证层(在 OAuth 之上,解决"身份登录")     │
└─────────────────────────────────────────────────────────┘

OAuth 2.0 角色

┌─────────────┐   1.授权请求    ┌──────────────┐
│  Resource   │───────────────→│ Authorization│
│   Owner     │←───2.授权许可──│   Server     │
│  (用户)     │                │  (授权服务器) │
└─────────────┘                └──────────────┘
                                      ↑ 3.令牌
┌─────────────┐                       │
│   Client    │───────────────────────┘
│ (第三方应用) │   4.携带令牌访问资源
└─────────────┘          ↓
                    ┌──────────────┐
                    │  Resource    │
                    │   Server     │
                    │  (资源服务器) │
                    └──────────────┘
角色 说明
Resource Owner 资源所有者(用户)
Client 第三方应用
Authorization Server 授权服务器(颁发令牌)
Resource Server 资源服务器(校验令牌、提供资源)

四种授权模式

1. 授权码模式(Authorization Code,最推荐)

适用:有后端的 Web 应用(能安全保存 client_secret)

流程:
1. 用户点击登录 → 浏览器跳转授权服务器
   GET /authorize?response_type=code&client_id=xxx
       &redirect_uri=https://app/callback&scope=read&state=xyz
2. 用户在授权页登录并同意
3. 授权服务器回调:GET https://app/callback?code=ABC&state=xyz
4. 后端用 code 换 token(服务端到服务端,安全)
   POST /token  { grant_type: authorization_code, code: ABC,
                  redirect_uri, client_id, client_secret }
5. 返回 access_token / refresh_token

为什么安全:token 不经过浏览器前端暴露,code 一次性

2. 授权码 + PKCE(移动/SPA 场景)

问题:公共客户端无法安全保存 client_secret

PKCE(Proof Key for Code Exchange):
1. 客户端生成 code_verifier(随机串)
2. 计算 code_challenge = SHA256(code_verifier)
3. 授权请求带 code_challenge
4. 换 token 时带 code_verifier
5. 服务器校验 SHA256(code_verifier) == code_challenge

→ 防止授权码被拦截后盗用

3. 客户端凭证模式(Client Credentials)

适用:服务间通信,无用户参与

POST /token
  grant_type=client_credentials
  &client_id=xxx
  &client_secret=yyy
  &scope=api.read

→ 直接返回 access_token(代表"应用自己"而非用户)

4. 密码模式(Password,已不推荐)

适用:第一方应用,且无法用其他模式

POST /token
  grant_type=password&username=u&password=p
  &client_id=xxx

问题:客户端需接触用户密码,安全风险高,OAuth 2.1 已移除

模式选择:

场景 推荐模式
Web 应用(有后端) 授权码模式
SPA / 移动 App 授权码 + PKCE
服务间调用 客户端凭证
第一方可信应用 授权码(避免密码模式)

JWT 令牌详解

结构:三段式

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxIn0 . SflKxwRJ...
      Header (Base64Url)            Payload (Base64Url)   Signature

Header:
  { "alg": "HS256", "typ": "JWT" }

Payload(Claims):
  {
    "sub": "user_123",       // subject 主体
    "iss": "https://auth.example.com", // 签发者
    "aud": "api.example.com",          // 受众
    "exp": 1735689600,       // 过期时间
    "iat": 1735686000,       // 签发时间
    "nbf": 1735686000,       // 生效时间
    "jti": "unique-id",      // JWT ID,防重放
    "scope": "read write",   // 权限
    "roles": ["admin"]       // 角色
  }

Signature:
  HMACSHA256(
    base64UrlEncode(header) + "." + base64UrlEncode(payload),
    secret
  )

三种 Claims 类型:

类型 说明 示例
Registered 标准声明 sub, iss, aud, exp
Public 公共声明 自定义但需防冲突
Private 私有声明 业务自定义

JWT 的优缺点

✅ 优点:
  - 自包含:信息在令牌内,无需查库
  - 无状态:适合分布式、水平扩展
  - 跨域友好:可放 Authorization 头

❌ 缺点:
  - 无法主动撤销(签发后有效期内一直有效)
  - 体积较大(比 session id 大)
  - 敏感信息不可放(payload 仅 Base64,可解码)
  - 需妥善管理密钥与算法

安全风险与防范

风险 1:算法混淆攻击(alg=none / 非对称混淆)

攻击:把 header 的 alg 改成 none,或把 RS256 改成 HS256,
     用公钥当 HMAC 密钥伪造签名

防范:
1. 服务端固定校验算法,拒绝客户端指定的 alg
2. 校验时明确指定期望算法,不接受 none
3. 非对称场景公钥绝不用于对称验证

风险 2:令牌泄露

防范:
1. 传输必须 HTTPS
2. access_token 存内存,避免 localStorage(XSS 风险)
3. refresh_token 用 HttpOnly + Secure + SameSite Cookie
4. 短有效期 access_token + refresh_token 轮换
5. 支持 refresh_token 撤销与重用检测

风险 3:签名密钥管理

防范:
1. 密钥强度足够(HS256 密钥 ≥ 256 位随机)
2. 非对称更佳:授权服务器持私钥签名,资源服务器用公钥验证
3. 通过 JWKS(/.well-known/jwks.json)分发公钥,支持密钥轮换
4. 密钥托管在 KMS/Secret Manager,不入代码库

实战:令牌校验流程

// 资源服务器校验 JWT(伪代码)
public Claims validateToken(String token) {
    // 1. 解析并验证签名(使用缓存的 JWKS 公钥)
    Jws<Claims> jws = Jwts.parserBuilder()
        .setSigningKeyResolver(jwksResolver)  // 按 kid 选公钥
        .requireIssuer("https://auth.example.com")
        .requireAudience("api.example.com")
        .build()
        .parseClaimsJws(token);
    // parseClaimsJws 会自动校验:
    //   - 签名/算法
    //   - exp(过期)、nbf(生效时间)
    //   - iss、aud(若 require 配置)
    return jws.getBody();
}

// 2. 权限校验(scope / roles)
public void authorize(Claims claims, String requiredScope) {
    String scope = claims.get("scope", String.class);
    if (scope == null || !scope.contains(requiredScope)) {
        throw new AccessDeniedException("insufficient scope");
    }
}
# 网关统一校验(如 Spring Cloud Gateway)
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.example.com
          jwk-set-uri: https://auth.example.com/.well-known/jwks.json

最佳实践

  1. 优先授权码 + PKCE:公共客户端不再用隐式/密码模式
  2. access_token 短有效期(如 15 分钟),refresh_token 长效但可撤销
  3. 令牌轮换:refresh_token 一次性使用,重放即撤销整条令牌链
  4. 最小权限 scope:按需授权,避免一次性要全权限
  5. 强校验:算法固定、iss/aud/exp 全校验、JWKS 密钥轮换
  6. 不存敏感信息:JWT payload 可解码,别放身份证、手机号
  7. 集中式吊销:如需即时撤销,可引入令牌内省(introspection)或黑名单
  8. 审计与监控:记录令牌签发、失败校验、异常重放

总结

概念 要点
OAuth 2.0 授权框架,四种模式,授权码(+PKCE)最推荐
OIDC 认证层,在 OAuth 上增加 id_token
JWT 自包含无状态令牌,三段 Base64Url + 签名
安全核心 固定算法、HTTPS、短有效期、刷新轮换、JWKS
撤销难题 JWT 天然难撤销,用短效 + introspection 缓解

设计认证授权体系的核心:OAuth 负责"如何安全地拿到令牌",JWT 负责"令牌如何自证身份与权限",安全则取决于算法、密钥、有效期与传输的每一处细节。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。