OAuth 是定义授权方式的框架,JWT 是定义如何封装和传输声明的令牌格式。二者解决不同问题,大多数生产系统会同时使用这两种技术。JWT 和 OAuth 几乎出现在每一个身份验证系统中,这也是工程师常将二者混为一谈的原因,但这种关联并不意味着它们是同一事物。
二者的混淆会导致实际的安全漏洞,尤其是在机器对机器通信场景中,这类场景下工作负载无法使用浏览器登录或多因素身份验证(MFA)提示。明确 JWT 的边界和 OAuth 的边界,是正确实现工作负载身份验证的第一步。
核心要点
- OAuth 是授权框架;JWT 是令牌格式。OAuth 定义流程,JWT 定义数据结构。
- OAuth 决定请求方可访问的资源,不验证请求方身份,身份验证是构建在 OAuth 之上的 OpenID Connect(OIDC)的职责。
- OAuth 通常会将 JWT 作为其访问令牌颁发,这也是二者频繁同时出现并被混为一谈的原因。
- 对于工作负载而言,基于证明的身份验证和短期凭证可消除访问流程中对长期客户端密钥的需求。
JWT 与 OAuth 的区别
OAuth 2.0 规定应用程序如何在不暴露凭证的情况下获取有限访问权限。它指定了适用于不同场景的多种授权流程,并管理访问令牌的生命周期:颁发、范围限定、刷新和撤销。OAuth 决定请求方可访问的资源,而非请求方的身份。
授权码流程专为 Web 应用设计,这类应用的服务器端代码可安全存储密钥并处理用户同意。客户端凭证流程专为无用户交互的机器对机器通信场景设计:服务通过客户端 ID 和密钥直接向授权服务器进行身份验证以获取访问令牌。令牌交换(RFC 8693)使工作负载能够在信任边界之间交换一种令牌类型,例如将 AWS IAM 令牌交换为 Azure 访问令牌。
JSON Web Token(JWT)是一种紧凑、URL 安全的令牌格式,用于以签名 JSON 对象的形式在各方之间传输信息。每个 JWT 都包含声明签名算法的头部、携带声明(颁发者、主体、受众、过期时间、权限等)的有效载荷,以及证明令牌未被篡改的加密签名。由于所有必要信息都嵌入在令牌本身中,接收服务可在本地验证 JWT,无需回调中央服务器。
核心区别在于,OAuth 是定义流程的协议,而 JWT 是定义数据结构的格式。在实践中,OAuth 常将 JWT 作为其访问令牌颁发,这也是二者频繁同时出现的原因。
| JWT | OAuth | |
| 是什么 | 令牌格式(RFC 7519) | 授权框架(RFC 6749) |
| 主要作用 | 在各方之间封装和传输已签名的声明 | 委托和控制对受保护资源的访问 |
| 有状态性 | 自包含令牌格式,通常可在本地验证 | 授权框架,可使用自包含令牌或不透明令牌 |
| 撤销 | 在无额外基础设施的情况下,无法在过期前撤销 | 令牌可在授权服务器处撤销 |
| 范围 | 携带声明;不定义令牌的颁发或刷新方式 | 定义颁发、刷新、范围限定和撤销工作流 |
| 可单独使用? | 是的,适用于受信任各方之间的简单已签名断言 | 是的,但需要令牌格式(通常为 JWT)来携带访问信息 |
| 常见组合 | 在 OAuth 流程中用作令牌格式 | 将 JWT 作为访问令牌颁发,并使用 OIDC 进行身份验证 |
JWT 与 OAuth 如何协同工作
在大多数生产系统中,OAuth 和 JWT 是互补而非竞争的关系。OAuth 2.0 定义授权流程和令牌生命周期。OpenID Connect(OIDC)是构建在 OAuth 2.0 之上的身份层,通过颁发包含已验证实体声明的 JWT 形式的 ID 令牌来实现身份验证。
使用这两种协议的典型工作负载身份验证流程如下:
- 服务需要访问受保护资源,并通过客户端凭证流程向 OAuth 授权服务器进行身份验证。
- 授权服务器验证凭证、评估访问策略,并颁发包含授权范围和声明的 JWT 访问令牌。
- 服务将此 JWT 提交给资源服务器,资源服务器在授予访问权限前会验证签名和声明。
这种组合之所以可行,是因为 OAuth 处理了令牌颁发和生命周期管理的复杂性,而 JWT 使资源服务器能够在本地验证令牌,无需在每次请求时回调授权服务器。在拥有数百个微服务的分布式系统中,这种本地验证可消除每个 API 调用的网络往返。
JWT 和 OAuth 的混淆通常源于它们在该流程中的重叠存在。当工程师提到“OAuth 身份验证”时,他们通常指的是 OAuth 授权与通过 OIDC 颁发的 JWT 实现的基于令牌的身份验证的结合。明确这种区别可防止架构错误,例如在没有 OAuth 框架管理其生命周期的情况下,使用原始 JWT 进行授权决策。
OAuth 2.1 与工作负载认证
OAuth 2.1 将多年的安全经验教训整合为单一规范。目前它处于 IETF 草案的后期阶段,尚未作为最终 RFC 发布,但已被主要授权服务器广泛采用。
该规范弃用了隐式流程和资源所有者密码凭证流程。它要求所有授权码流程都使用 PKCE。
公共客户端的刷新令牌必须是发送方受限或一次性使用的,这使得轮换成为实践中的标准实现方式。
OAuth 2.1 还建议通过相互 TLS 将访问令牌绑定到客户端,这是与刷新令牌轮换不同的机制,旨在防止被盗令牌在其他地方重放。
对于工作负载和机器对机器用例,OAuth 2.1 标准化了客户端凭证的交换方式、访问令牌的范围限定方式,以及令牌交换(RFC 8693)在不同环境中的工作方式。
用于 AI 代理互操作性的新兴框架,包括模型上下文协议(MCP),都依赖于这些原则。OAuth 2.1 支持使用短期、可验证的 JWT 在代理、服务和 API 之间进行标准化授权,无需持久密钥。
将 OAuth 和 JWT 应用于工作负载会引入人类身份验证中不存在的挑战。人类可以使用 MFA、推送通知和浏览器登录,而工作负载无法做到这些。
工作负载依赖于证书、证明或令牌,这意味着传统的 OAuth 客户端凭证方法(将客户端密钥存储在容器镜像或环境变量中)会创建持久的攻击面。
基于证明的身份验证通过完全消除长期密钥来解决此问题。工作负载不管理存储的凭证,而是使用关于其运行时环境的加密可验证身份声明进行身份验证:它们运行的云实例、所属的 Kubernetes 命名空间、主机的安全态势等。
授权服务器验证这些声明,并向工作负载需要访问的特定资源颁发范围限定的短期 JWT。工作负载从不处理持久密钥,且 JWT 在短时间后过期,从而限制了被拦截时的暴露范围。这就是 Aembit 的工作负载身份平台所基于的模型。
对于多云和混合环境,工作负载身份联合将此模型扩展到云边界之外。一个云中的工作负载提交其加密签名的身份令牌,目标授权服务器会验证该令牌并将其交换为范围限定到本地资源的新 JWT。这消除了在各云之间配置重复的服务账户和管理单独的凭证存储。单一加密验证的身份声明即可授予跨信任边界的访问权限。
为您的架构选择合适的方法
正确的实现方式取决于您运营的云数量、是否可以修改应用代码,以及您可以承受多少凭证管理开销。以下每种模式根据这些约束条件以不同方式应用 OAuth 和 JWT。
单云、单一身份提供商
使用云原生托管身份。AWS IAM 角色、Azure 托管身份和 GCP 服务账户在内部实现 OAuth 和 JWT,同时消除凭证存储。您的应用通过云的元数据服务进行身份验证,并接收 JWT 访问令牌,无需管理密钥。Kubernetes 服务账户在集群内提供 pod 级别的身份,可投影为 OIDC 令牌以与云 IAM 联合。此方法在单云内效果良好,但跨云访问需要联合。
多云或混合环境
实现具有集中策略的工作负载身份联合。使用 OAuth 2.0 令牌交换(RFC 8693)使一个云中的工作负载能够访问另一个云中的资源。工作负载提交其所在云的 JWT,目标授权服务器会验证该令牌并将其交换为范围限定到本地资源的新 JWT。这需要一个联合平台,能够验证来自多个颁发者的令牌并在各云之间执行一致的策略。好处是您无需在每个云中配置重复的服务账户和管理单独的凭证存储。单一加密验证的身份声明即可授予跨信任边界的访问权限。
无需修改代码的遗留应用
使用代理或中介模式。代理拦截微服务的传出请求,透明地处理 OAuth 流程、JWT 验证、令牌刷新和凭证注入。应用程序发出标准 HTTP 请求,无需知道代理正在管理身份验证。此模式对于 AI 代理和MCP 集成等无法修改应用代码的场景特别有用。
从何处开始
如果您正在为新项目评估 JWT 与 OAuth,请从明确要解决的问题开始。如果您需要为无状态验证封装已签名声明,则 JWT 是合适的格式;如果您需要跨服务委托和控制访问,则 OAuth 是合适的框架。大多数生产系统需要同时使用这两种技术:OAuth 管理授权生命周期,JWT 携带生成的访问信息。
对于工作负载身份验证,优先事项是消除静态凭证。存储在环境变量或配置文件中的每个客户端密钥都是可能被泄露、窃取或重用的凭证。转向通过 OAuth 流程颁发的基于证明的身份验证和短期 JWT 可完全消除该攻击面。首先审计哪些工作负载仍依赖长期客户端密钥,并确定哪些可以迁移到身份联合或托管身份。
Aembit 如何应用此方法
Aembit 的工作负载身份平台大规模实现了此模型:
- 它通过环境证明验证工作负载身份,然后使用该已验证身份授权和代理下游访问,无需工作负载存储客户端密钥。
- 它颁发带有自动刷新的短期 JWT 访问令牌,因此没有工作负载会持有长期凭证。
- 它处理跨云联合和条件访问策略执行,凭证注入透明进行,因此开发人员无需编写身份验证代码。
相关阅读
常见问题(FAQs)
我可以在不使用 OAuth 的情况下使用 JWT 吗?
是的。JWT 只是一种令牌格式,因此任何需要在两方之间封装和验证已签名声明的场景都可以使用 JWT,完全无需 OAuth。您完全控制的两个服务之间的会话令牌就是一个常见示例。您会失去 OAuth 的颁发、范围限定、刷新和撤销机制,因此需要自行负责构建和轮换这些已签名令牌。
我可以在不使用 JWT 的情况下使用 OAuth 吗?
是的。OAuth 不要求任何特定的令牌格式,许多实现会颁发不透明的引用式访问令牌,而非 JWT。JWT 只是最常见的选择,因为它们允许资源服务器在本地验证令牌,无需在每次请求时回调授权服务器。
OAuth 2.1 是否向后兼容 OAuth 2.0?
大部分兼容,但并非完全兼容。OAuth 2.1 直接弃用了隐式流程和资源所有者密码凭证流程,因此任何仍在使用这两种流程的应用都需要迁移到带 PKCE 的授权码流程,才能转向 OAuth 2.1。
为什么 OAuth 和 JWT 常被视为同一事物?
因为 OAuth 通常会将 JWT 作为其访问令牌颁发,所以二者几乎出现在每一个实际身份验证流程中。但 OAuth 是决定谁能获得令牌以及令牌范围的框架,而 JWT 只是令牌碰巧采用的格式。
JWT 可以在过期前撤销吗?
没有额外基础设施的话不行。JWT 通过其签名在本地验证,因此没有内置的方法像在 OAuth 授权服务器处撤销令牌那样提前使令牌失效。保持 JWT 生命周期较短是常见的缓解措施,因为被盗令牌仅在过期前有用。
JWT 和 OAuth 访问令牌有什么区别?
OAuth 访问令牌是 OAuth 框架定义的概念:客户端用来证明其有权访问资源的东西。JWT 是该访问令牌可能采用的一种特定、常见的格式。并非所有 OAuth 访问令牌都是 JWT,但大多数现代实现都会以这种方式颁发。