4. 鉴权基础:认证与授权、JWT 与 OAuth2.0

在多租户 SaaS 架构中,鉴权(Authentication & Authorization)是租户隔离的第一道防线。本章将厘清认证与授权的核心区别,并深入解析 JWT 令牌结构与 OAuth2.0 授权流程,为后续的拦截链路设计打下坚实基础。

4.1 认证(Authentication)与授权(Authorization)的区别

这两个概念常被混淆,但在架构设计中必须严格区分:

维度 认证(Authentication) 授权(Authorization)
核心问题 你是谁? 你能做什么?
目标 验证用户身份的真实性 授予用户访问特定资源的权限
执行时机 先于授权执行 认证通过后执行
常见机制 密码、MFA、SSO、生物识别 RBAC、ABAC、ACL、OAuth Scopes
传递信息 用户身份凭证(如 JWT sub) 权限声明(如 JWT roles/claims)
失败结果 401 Unauthorized 403 Forbidden
架构提示: 在 SaaS 网关层,认证通常由统一身份平台(IdP)完成,而授权则需结合租户上下文(tenant_id)与角色进行细粒度判断。切勿将两者混为一谈。

4.2 JWT 令牌结构详解

JSON Web Token(JWT)是目前多租户系统中最常用的令牌格式。它由三个 Base64URL 编码的部分组成,以点号(.)分隔:

# JWT 结构示例
# Header.Payload.Signature
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwidGVuYW50X2lkIjoiYWNtZS1jb3JwIiwicm9sZXMiOlsiYWRtaW4iLCJ1c2VyIl19.
s9HkL6xM5zR8vN2pQ3wY7aBcDeFgHiJkLmNoPqRsTuVwXyZ0

4.2.1 三部分核心解析

部分 内容 作用
Header 令牌类型(typ)与签名算法(alg) 声明如何签名
Payload 声明(Claims):sub, exp, tenant_id, roles 携带用户与租户信息
Signature 对 Header + Payload 的签名 防篡改验证
多租户关键字段: 在 Payload 中必须包含 tenant_id 或 org_id 声明,用于后续拦截器识别租户上下文。同时建议加入 roles 数组用于授权判断。
JWT 令牌结构分解 Header {"alg":"RS256", "typ":"JWT"} 签名算法声明 令牌类型声明 Payload {"sub":"user123", "tenant_id":"acme", "roles":["admin"], "exp":1700000000} 用户身份声明 租户隔离声明 权限角色声明 Signature HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 防篡改验证 完整性保证 ⚠ 令牌格式:Header.Payload.Signature,三部分均使用 Base64URL 编码

4.3 OAuth2.0 授权流程简介

OAuth2.0 是业界标准的授权框架,它定义了四种授权模式。在多租户 SaaS 中,最常用的是 授权码模式(Authorization Code Flow) 和 客户端凭证模式(Client Credentials Flow)。

4.3.1 核心角色

  • 资源所有者(Resource Owner): 用户,拥有数据访问权限。
  • 客户端(Client): 第三方应用或前端,请求访问资源。
  • 授权服务器(Authorization Server): 颁发令牌,负责认证与授权。
  • 资源服务器(Resource Server): 托管受保护资源,验证令牌。

4.3.2 授权码模式流程(最安全,适用于前端 + 后端)

  1. 用户访问客户端: 用户点击“登录”按钮。
  2. 客户端重定向到授权服务器: 携带 client_id, redirect_uri, scope, state。
  3. 用户认证并授权: 用户在授权服务器登录,并同意授权。
  4. 授权服务器返回授权码: 重定向回客户端,URL 中包含 code。
  5. 客户端用授权码换取令牌: 后端通过 code + client_secret 请求 token endpoint。
  6. 授权服务器返回 Access Token + Refresh Token: 客户端使用 Access Token 访问资源。
OAuth2.0 授权码模式流程 用户 客户端 授权服务器 1. 访问应用 2. 重定向(client_id, redirect_uri) 3. 用户认证并授权 4. 返回授权码(code) 5. 用 code + client_secret 换令牌 6. 返回 Access Token + Refresh Token 资源服务器 7. 携带 Access Token 请求资源 ⚠ 授权码模式确保令牌只在后端传输,避免前端暴露 client_secret,是多租户 SaaS 的首选方案

4.4 多租户场景下的鉴权要点

租户隔离陷阱: 仅验证 JWT 签名是不够的。必须确保每个请求的 tenant_id 与当前登录用户所属租户一致,防止跨租户越权访问(Horizontal Privilege Escalation)。
  • 令牌内嵌租户上下文: 在 JWT Payload 中强制包含 tenant_id 和 roles。
  • OAuth2.0 Scope 与租户绑定: 授权时限定 scope 为 tenant:{tenant_id}:read 格式。
  • 令牌验证链路: 网关层验证签名 → 提取 tenant_id → 注入请求上下文 → 业务层校验权限。
  • Refresh Token 轮转: 每次刷新令牌时重新验证租户状态,防止租户被禁用后令牌仍有效。
最佳实践: 使用 RS256(非对称算法)签名 JWT,授权服务器持有私钥,资源服务器仅需公钥验证,避免密钥分发风险。同时设置较短的 Access Token 有效期(如 15 分钟),配合 Refresh Token 实现无感续期。