| 互联网草案 | OAuth 2.1 授权框架 | 2026 年 3 月 |
| Hardt 等 | 有效期至 2026 年 9 月 3 日 | [页] |
OAuth 2.1 授权框架使 应用程序能够获得对受保护资源的有限访问权限,这可以通过 代表资源所有者来编排资源所有者与授权服务之间的批准交互 来实现,也可以通过允许该应用程序以其自身名义获得访问权限来实现。本 规范取代并废止了 RFC 6749 中描述的 OAuth 2.0 授权 框架以及 RFC 6750 中的承载令牌用法。¶
本说明将在发布为 RFC 前移除。¶
本文档的讨论在 OAuth 工作组邮件列表(oauth@ietf.org)上进行, 该列表的归档位于 https://mailarchive.ietf.org/arch/browse/oauth/。¶
本草案的源代码和议题跟踪器可在 https://github.com/oauth-wg/oauth-v2-1 找到。¶
本互联网草案完全遵循 BCP 78 和 BCP 79 的 规定提交。¶
互联网草案是互联网工程任务组(IETF)的工作文档。 请注意,其他组织也可以将工作文档作为互联网草案分发。 当前互联网草案的列表位于 https://datatracker.ietf.org/drafts/current/。¶
互联网草案是有效期最长为六个月的草案文档, 可在任何时候由其他文档更新、取代或废止。 将互联网草案用作参考资料,或以“进行中的工作”之外的方式 引用它们,都是不合适的。¶
本互联网草案将于 2026 年 9 月 3 日到期。¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
OAuth 通过将客户端的角色与资源所有者的角色分离, 向客户端-服务器认证模型引入了一个授权层。在 OAuth 中, 客户端请求访问由资源所有者控制并托管在资源服务器上的资源。 客户端不是使用资源所有者的凭据来访问受保护资源, 而是获得一个访问令牌——一种表示特定访问属性集合 (例如范围和生命周期)的凭据。访问令牌由授权服务器 在资源所有者批准后颁发给客户端。客户端使用访问令牌 访问由资源服务器托管的受保护资源。¶
在较旧且限制更多的客户端-服务器认证模型中, 客户端通过使用资源所有者的凭据向服务器认证, 来请求服务器上的访问受限资源(受保护资源)。 为了向应用程序提供对受限资源的访问,资源所有者会与 应用程序共享其凭据。这会产生若干问题和限制:¶
应用程序需要存储资源所有者的凭据以供将来使用, 通常是以明文形式存储的密码。¶
服务器需要支持密码认证,尽管密码存在固有的 安全弱点。¶
应用程序会获得对资源所有者受保护资源的过宽访问权限, 使资源所有者无法限制访问持续时间,也无法将访问限制在 一小部分资源上。¶
资源所有者经常在其他不相关服务中重复使用密码, 尽管最佳安全实践并不建议这样做。这种密码重用意味着 一个服务中的漏洞或泄露可能会对完全不相关的服务产生 安全影响。¶
资源所有者无法在不撤销所有第三方访问的情况下 撤销单个应用程序的访问,并且必须通过更改密码来做到这一点。¶
任何应用程序被攻破都会导致最终用户密码以及该密码保护的 所有数据被攻破。¶
OAuth 的一个使用示例是,最终用户(资源所有者)授予财务 管理服务(客户端)访问其存储在银行服务(资源服务器)中的 敏感交易历史记录,而无需与该财务管理服务共享用户名和 密码。相反,用户直接向其金融机构的服务器(授权服务器)进行认证, 该服务器向财务管理服务颁发特定于委派的凭据 (访问令牌)。¶
这种关注点分离还提供了使用更高级用户认证方法的能力, 例如多因素认证,甚至无密码认证,而无需对应用程序进行任何修改。 由于所有用户认证逻辑都由授权服务器处理,应用程序无需关心 实现任何特定认证机制的具体细节。这使授权服务器能够管理 用户认证策略,并且即使将来更改这些策略,也无需与应用程序 协调变更。¶
授权层还可以简化资源服务器判断请求是否已获授权的方式。 传统上,在认证客户端之后,每个资源服务器都会在每次 API 调用时 评估策略,以计算客户端是否被授权。在分布式系统中, 策略需要同步到所有资源服务器,或者资源服务器必须调用中央策略 服务器来处理每个请求。在 OAuth 中,策略评估只在授权服务器 创建新的访问令牌时执行。如果已授权访问体现在访问令牌中, 资源服务器就不再需要评估策略,而只需验证访问令牌。 当应用程序代表资源所有者行事,或代表自身行事时, 这种简化都适用。¶
OAuth 是一种授权协议,而不是认证协议,因为 OAuth 并未定义 实现用户认证所必需的组件。如果目标是认证用户, 则需要一种认证协议。一个示例是 OpenID Connect [OpenID.Connect],它构建在 OAuth 之上,以提供认证协议所需的安全特性和必要组件。¶
访问令牌表示授予客户端的授权。客户端向专有 API 提交访问令牌, 该 API 返回资源所有者的用户标识符,然后将该 API 的结果作为 认证用户的代理,这是一种常见做法。此做法不属于 OAuth 标准或安全考虑的一部分,也可能并未被资源所有者所考虑。 实现者在采用此做法之前,应仔细查阅资源服务器的文档。¶
本规范设计用于 HTTP [RFC9110]。在 HTTP 之外的任何协议上使用 OAuth 均不在范围内。¶
自 OAuth 2.0 授权框架 [RFC6749] 于 2012 年 10 月发布以来,它已经由 OAuth 2.0 for Native Apps [RFC8252]、 OAuth Security Best Current Practice [RFC9700] 以及 OAuth 2.0 for Browser-Based Apps [I-D.ietf-oauth-browser-based-apps] 更新。 OAuth 2.0 Authorization Framework: Bearer Token Usage [RFC6750] 也已通过 [RFC9700] 更新。本 标准轨道规范整合了所有这些文档中的信息,并移除了 [RFC9700] 中发现的不安全功能。¶
OAuth 定义了四个角色:¶
能够授予对受保护资源访问权限的实体。 当资源所有者是人时,称为最终用户。有时缩写为 “RO”。¶
托管受保护资源的服务器,能够使用访问令牌接受并响应 受保护资源请求。资源服务器通常可通过 API 访问。 有时缩写为 “RS”。¶
代表资源所有者并在其授权下发出受保护资源请求的应用程序。 “客户端”一词并不暗示任何特定的实现特征(例如, 应用程序是在服务器、桌面还是其他设备上执行)。¶
在成功认证资源所有者并获得授权后,向客户端颁发访问令牌的服务器。 有时缩写为 “AS”。¶
本规范的大部分内容定义了客户端与授权服务器之间、 以及客户端与资源服务器之间的交互。¶
授权服务器与资源服务器之间的交互超出本规范范围, 但已经定义了一些扩展,以提供资源服务器与授权服务器之间 互操作性的选项。授权服务器可以与资源服务器是同一台服务器, 也可以是单独的实体。单个授权服务器可以颁发被多个资源服务器 接受的访问令牌。¶
资源所有者与授权服务器之间的交互 (例如最终用户如何在授权服务器上认证自己) 也超出本规范范围,但有一些例外,例如围绕提示最终用户同意的 安全考虑。¶
当资源所有者是最终用户时,用户将与客户端交互。 当客户端是基于 Web 的应用程序时,用户将通过用户代理与客户端交互 (如 [RFC9110] 的 第 3.5 节 所述)。 当客户端是原生应用程序时,用户将直接通过操作系统与客户端交互。 有关更多详细信息,请参见 第 2.1 节。¶
+--------+ +---------------+
| |--(1)- Authorization Request ->| Resource |
| | | Owner |
| |<-(2)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(3)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(4)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(5)----- Access Token ------>| Resource |
| | | Server |
| |<-(6)--- Protected Resource ---| |
+--------+ +---------------+
图 1 中所示的抽象 OAuth 2.1 流程描述了 四个角色之间的交互,并包括以下步骤:¶
客户端向资源所有者请求授权。 授权请求可以直接向资源所有者发出(如图所示), 或者最好通过授权服务器作为中介间接发出。¶
客户端接收授权授予,这是一种表示资源所有者授权的凭据, 使用本规范中定义的一种授权授予类型来表示, 或使用扩展授予类型来表示。授权授予类型取决于客户端 请求授权所使用的方法,以及授权服务器支持的类型。¶
客户端通过向授权服务器认证并提交授权授予来请求访问令牌。¶
授权服务器认证客户端并验证授权授予; 如果有效,则颁发访问令牌。¶
客户端从资源服务器请求受保护资源, 并通过提交访问令牌进行认证。¶
资源服务器验证访问令牌; 如果有效,则为该请求提供服务。¶
客户端从资源所有者获得授权授予的首选方法 (图中步骤 (1) 和 (2) 所示)是使用授权服务器作为中介, 这在 第 4.1 节 的 图 3 中说明。¶
访问令牌是用于访问受保护资源的凭据。访问令牌是一个 表示向客户端颁发的授权的字符串。¶
该字符串对客户端而言被认为是不透明的,即使它具有结构。 客户端不得期望能够解析访问令牌值。除资源服务器预期的内容外, 授权服务器不需要使用一致的访问令牌编码或格式。¶
资源所有者授予客户端的访问由授权服务器创建的访问令牌表示。 访问令牌生命周期较短,以降低访问令牌泄露的影响范围。 访问令牌的过期时间由授权服务器设置。¶
根据授权服务器实现,令牌字符串可以由资源服务器用于检索 授权信息,或者令牌可以以可验证的方式自行包含授权信息 (即由已签名数据载荷组成的令牌字符串)。令牌检索机制的一个示例是 Token Introspection [RFC7662],其中 RS 调用 AS 上的端点来验证客户端提交的令牌。 结构化令牌格式的一个示例是 JWT Profile for Access Tokens [RFC9068], 这是一种将访问令牌数据编码并签名为 JSON Web Token [RFC7519] 的方法。¶
为了让客户端使用访问令牌,可能需要其他认证凭据, 这些内容超出本规范范围。这通常称为发送方约束的访问令牌, 例如 DPoP [RFC9449] 和 Mutual TLS Certificate-Bound Access Tokens [RFC8705]。¶
访问令牌提供了一个抽象层,将不同的授权构造 (例如用户名和密码)替换为资源服务器理解的单个令牌。 这种抽象支持颁发比用于获得访问令牌的授权授予更具限制性的访问令牌, 同时也消除了资源服务器理解大量认证方法的需要。¶
访问令牌可以根据资源服务器的安全要求具有不同的格式、 结构和使用方法(例如加密属性)。访问令牌属性以及用于访问 受保护资源的方法可以扩展到本规范描述之外。¶
访问令牌(以及任何机密访问令牌属性)在传输和存储中必须 保持机密,并且只能在授权服务器、该访问令牌对其有效的资源服务器, 以及被颁发该访问令牌的客户端之间共享。¶
授权服务器必须确保未经授权方无法生成、修改或猜测出 有效的访问令牌。¶
访问令牌旨在以低于授予访问权限的用户所拥有权限的 权限颁发给客户端。这称为有限“范围”的访问令牌。 授权服务器和资源服务器可以使用此范围机制来限制特定客户端 可以拥有的资源类型或访问级别。¶
例如,客户端可能只需要对用户资源的“读取”访问权限, 而不需要更新资源,因此客户端可以请求授权服务器定义的只读范围, 并获得不能用于更新资源的访问令牌。这需要授权服务器、 资源服务器和客户端之间进行协调。授权服务器向客户端提供 请求特定范围的能力,并将这些范围与颁发给客户端的访问令牌 相关联。随后资源服务器负责在收到有限范围访问令牌时执行范围。¶
OAuth 不定义任何范围值;范围由授权服务器, 或 OAuth 的扩展或配置文件定义。定义范围的一个此类扩展是 [OpenID.Connect],它定义了一组范围, 用于提供对用户个人资料信息的细粒度访问。建议避免定义 与已知扩展中的范围冲突的自定义范围。¶
为了请求有限范围的访问令牌,客户端根据所使用的
授予类型,在授权端点或令牌端点使用 scope
请求参数。相应地,授权服务器使用 scope
响应参数告知客户端所颁发访问令牌的范围。¶
scope 参数的值表示为以空格分隔的区分大小写字符串列表。 这些字符串由授权服务器定义。如果该值包含多个以空格分隔的字符串, 它们的顺序无关紧要,并且每个字符串都会向所请求范围添加 一个额外的访问范围。¶
scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
¶
授权服务器可以根据授权服务器策略或资源所有者的指示,
完全或部分忽略客户端请求的范围。如果已颁发访问令牌的范围
与客户端请求的范围不同,授权服务器必须在令牌响应
(第 3.2.3 节)
中包含 scope 响应参数,以告知客户端实际授予的范围。¶
如果客户端在请求授权时省略 scope 参数, 授权服务器必须要么使用预定义的默认值处理该请求, 要么使请求失败并指示无效范围。授权服务器应记录其范围要求 和默认值(如果已定义)。¶
承载令牌是一种安全令牌,其属性是任何持有该令牌的主体 (“承载者”)都可以以任何其他持有该令牌的主体所能使用的方式 使用该令牌。使用承载令牌不要求承载者证明其持有加密密钥材料 (持有证明)。¶
承载令牌可以通过 DPoP [RFC9449] 和 mTLS [RFC8705] 等持有证明规范进行增强,以提供持有证明特性。¶
为了防止访问令牌泄露,客户端与资源服务器之间的通信交互 必须按照 第 1.5 节 所述使用机密性和完整性保护。¶
对承载令牌的特定结构或格式没有要求。如果承载令牌是 对授权信息的引用,则攻击者必须不可行地猜测此类引用, 例如使用足够长的加密随机字符串。如果承载令牌使用编码机制 将授权信息包含在令牌本身中,则访问令牌必须使用足够的完整性保护 来防止令牌被修改。JSON Web Token Profile for Access Tokens [RFC9068] 中描述了访问令牌的一种 编码和签名机制示例。¶
发送方约束的访问令牌将访问令牌的使用绑定到特定发送方。 该发送方有义务证明其知道某个秘密,作为接收方 (例如资源服务器)接受该访问令牌的前提条件。¶
授权服务器和资源服务器应使用用于发送方约束访问令牌的机制, 例如 OAuth Demonstration of Proof of Possession (DPoP) [RFC9449] 或 Mutual TLS for OAuth 2.0 [RFC8705]。 请参见 [RFC9700] 的 第 4.10.1 节,以防止被窃取和泄露的 访问令牌被滥用。¶
建议在客户端和资源服务器之间使用端到端 TLS。 如果 TLS 流量需要在中介处终止,请参阅 [RFC9700] 的 第 4.13 节 以获得进一步安全建议。¶
实现必须使用一种机制来提供通信认证、完整性和机密性, 例如 Transport-Layer Security [RFC8446], 以保护内容或标头字段中的明文凭据和令牌交换,防止窃听造成重放 (例如,参见 第 2.4.1 节、 第 7.5.1 节、 第 3.2 节 和 第 1.4.2 节)。¶
所有 OAuth 协议 URL(由 AS、RS 和客户端暴露的 URL)
都必须使用 https 方案,回环接口重定向 URI 除外,
后者可以使用 http 方案。
使用 https 时,必须按照
[RFC9110] 的
第 4.3.4
节 检查 TLS 证书。
在撰写本文时,TLS 版本 1.3 [RFC8446]
是最新版本。¶
实现也可以支持满足其安全要求的其他传输层安全机制。¶
TLS 版本和算法的确定超出本规范范围。 有关传输层安全的最新建议,请参阅 [BCP195], 有关证书验证和其他安全考虑,请参阅相关规范。¶
本规范广泛使用 HTTP 重定向,其中客户端或授权服务器将 资源所有者的用户代理引导到另一个目的地。虽然本规范中的示例 展示了 HTTP 302 状态码的使用,但除了 HTTP 307 之外, 允许使用通过用户代理可用的任何其他方法来完成此重定向, 并且这被认为是实现细节。有关详细信息,请参见 第 7.5.3 节。¶
OAuth 2.1 提供了一个具有明确定义安全属性的丰富授权框架。¶
本规范将若干必需组件部分或完全未定义 (例如客户端注册、授权服务器能力、端点发现)。 其中一些行为在可选扩展中定义,实现可以选择使用,例如:¶
OAuth 2.1 与 OAuth 2.0 兼容,同时应用了来自已知最佳当前实践的 扩展和限制。具体而言,OAuth 2.0 核心中未指定的功能 (例如 PKCE)在 OAuth 2.1 中是必需的。此外,OAuth 2.0 中可用的一些功能 (例如隐式授予或资源所有者凭据授予类型)未在 OAuth 2.1 中指定。 另外,OAuth 2.0 中允许的一些行为在 OAuth 2.1 中受到限制, 例如 OAuth 2.1 要求的重定向 URI 严格字符串匹配。¶
本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“NOT RECOMMENDED”、 “MAY” 和 “OPTIONAL” 按照 BCP 14 [RFC2119] [RFC8174] 中的描述解释, 但仅当它们以全大写形式出现时才如此,如此处所示。¶
本规范使用 [RFC5234] 中的扩展巴科斯-诺尔范式(ABNF)表示法。此外,规则 URI-reference 引自 “Uniform Resource Identifier (URI): Generic Syntax” [RFC3986]。¶
某些与安全相关的术语应按 [RFC4949] 中定义的含义理解。 这些术语包括但不限于:“attack”、“authentication”、“authorization”、“certificate”、 “confidentiality”、“credential”、“encryption”、“identity”、“sign”、 “signature”、“trust”、“validate” 和 “verify”。¶
术语 “content” 应按 [RFC9110] 的 第 6.4 节 中的描述解释。¶
术语 “user agent” 应按 [RFC9110] 的 第 3.5 节 中的描述解释。¶
除非另有说明,所有协议参数名称和值均区分大小写。¶
在启动协议之前,客户端必须已在授权服务器处建立一个标识符 (第 2.2 节)。 客户端标识符与授权服务器建立的方式超出本规范范围, 但通常涉及客户端开发者在授权服务器的网站上手动注册客户端 (在创建账户并同意该服务的服务条款之后),或者使用 Dynamic Client Registration [RFC7591]。 扩展也可以定义其他用于建立客户端注册的编程方法。¶
客户端注册不要求客户端与授权服务器直接交互。 在授权服务器支持时,注册可以依赖其他方式来建立信任并获得所需的 客户端属性(例如重定向 URI、客户端类型)。例如,可以使用自颁发或 第三方颁发的断言完成注册,或者由授权服务器通过可信通道执行客户端发现。¶
客户端注册必须包括:¶
授权服务器所需的任何其他信息 (例如应用程序名称、网站、描述、标志图像、接受法律条款)。¶
Dynamic Client Registration [RFC7591] 定义了一个通用客户端数据模型, 即使在手动客户端注册中也可以使用。¶
OAuth 2.1 根据客户端是否能够安全地向授权服务器认证, 定义了两种客户端类型。¶
任何具有凭据的客户端都必须采取预防措施,防止其凭据泄露和滥用。¶
客户端认证允许授权服务器确保其在 OAuth 流程中
与某个特定客户端(由其 client_id 标识)进行交互。
授权服务器可能会基于其对确实正在与合法客户端通信的信心,
对诸如是在每次授权时提示用户同意还是仅第一次提示等事项作出策略决策。¶
授权服务器是否以及如何验证客户端身份或提供/运营此客户端的 参与方身份,超出本规范范围。授权服务器在决定是否允许客户端 访问更敏感的资源和操作(例如客户端凭据授予类型)以及多频繁地提示用户同意时, 应考虑其对客户端身份的信心水平。¶
不要求授权服务器支持特定客户端类型。¶
单个 client_id 不应被视为超过一种客户端类型。¶
本规范围绕以下客户端配置文件设计:¶
Web 应用程序是在 Web 服务器上运行的客户端。 资源所有者通过在其设备上的用户代理中渲染的 HTML 用户界面 访问该客户端。客户端凭据以及颁发给客户端的任何访问令牌 都存储在 Web 服务器上,不会暴露给资源所有者,也无法由其访问。¶
基于浏览器的应用程序是一种客户端,其客户端代码 从 Web 服务器下载,并在资源所有者所用设备上的用户代理 (例如 Web 浏览器)内执行。协议数据和凭据很容易被资源所有者访问 (并且通常可见)。如果此类应用程序希望使用客户端凭据, 建议使用 backend for frontend 模式。由于此类应用程序驻留在用户代理中, 因此它们在请求授权时可以无缝利用用户代理能力。¶
原生应用程序是安装并执行在资源所有者所用设备上的客户端。 协议数据和凭据可被资源所有者访问。假定应用程序中包含的任何 客户端认证凭据都可以被提取。动态颁发的访问令牌和刷新令牌 可以获得可接受级别的保护。在某些平台上,这些凭据受到保护, 不会被同一设备上的其他应用程序访问。如果此类应用程序希望使用 客户端凭据,建议使用 backend for frontend 模式,或者在运行时使用 Dynamic Client Registration [RFC7591] 颁发凭据。¶
每个客户端都在授权服务器的上下文中由客户端标识符标识—— 这是一个表示客户端提供的注册信息的唯一字符串。虽然授权服务器通常 自行颁发客户端标识符,但它也可以服务由授权服务器之外的一方 创建客户端标识符的客户端。客户端标识符不是秘密;它会暴露给 资源所有者,并且不得单独用于客户端认证。客户端标识符在 授权服务器的上下文中是唯一的。¶
客户端标识符是一个不透明字符串,其大小由本规范保持未定义。 客户端应避免对标识符大小作出假设。授权服务器应记录其颁发的 任何标识符的大小。¶
如果授权服务器支持由授权服务器之外的参与方颁发客户端标识符的 客户端,则授权服务器应采取预防措施,以避免客户端冒充资源所有者, 如 第 7.4 节 所述。¶
客户端重定向端点(也称为“重定向端点”) 是客户端的 URI,授权服务器在完成与资源所有者的交互后, 将用户代理重定向回该 URI。¶
授权服务器将用户代理重定向到客户端在客户端注册过程中 先前与授权服务器建立的一个重定向端点。¶
重定向 URI 必须是 [RFC3986] 的 第 4.3 节 所定义的绝对 URI。重定向 URI 可以包含查询字符串组件 (附录 C.1),在添加额外查询参数时必须保留该组件。 重定向 URI 不得包含片段组件。¶
授权服务器必须要求客户端注册其完整的重定向 URI (包括路径组件)。授权服务器必须拒绝指定了与已注册 URI 不完全匹配的重定向 URI 的授权请求;回环重定向除外, 其中除端口 URI 组件外仍要求精确匹配,详见 第 4.1.1 节。¶
授权服务器可以允许客户端注册多个重定向 URI。¶
注册可以带外发生,例如在授权服务器配置客户端信息的手动步骤; 也可以在运行时发生,例如在 Pushed Authorization Requests [RFC9126] 中的初始 POST。¶
对于基于私用 URI 方案的重定向 URI,
授权服务器应强制执行 第 8.4.3 节
中的要求,即客户端使用
基于反向域名的方案。至少,应拒绝任何不包含句点字符
(.)的私用 URI 方案。¶
除了抗冲突属性之外,这还有助于在两个应用声称相同私用
URI 方案(一方恶意行事)的争议中证明所有权。
例如,如果两个应用都声称 com.example.app,
example.com 的所有者可以请求应用商店运营者移除
假冒应用。如果使用的是通用 URI 方案,则此类请求更难证明。¶
客户端不得暴露会将用户浏览器转发到从查询参数获得的任意 URI 的 URL(“开放重定向器”),如 第 7.12 节 所述。 开放重定向器可能导致授权码和访问令牌被外泄。¶
如果需要,客户端可以使用 state 请求参数实现
每个请求的自定义,而不是逐请求改变重定向 URI。¶
如果客户端已注册多个重定向 URI,
则客户端必须使用 redirect_uri 请求参数
(第 4.1.1 节)
在授权请求中包含一个重定向 URI。
如果客户端只注册了单个重定向 URI,则
redirect_uri 请求参数是可选的。¶
客户端必须防止跨站请求伪造(CSRF)攻击。
在此上下文中,CSRF 指的是并非源自授权服务器,
而是源自恶意第三方的对重定向端点的请求
(有关详细信息,请参见
[RFC6819] 的
第
4.4.1.8 节)。
已确认授权服务器支持 code_challenge 参数的客户端
可以依赖该机制提供的 CSRF 保护。在 OpenID Connect 流程中,
验证 nonce 参数会提供 CSRF 保护。否则,
必须使用 state 参数中携带并安全绑定到用户代理的一次性
CSRF 令牌进行 CSRF 保护(参见
第 7.9 节)。¶
当 OAuth 客户端只能与一个授权服务器交互时,不需要混淆防御。 然而,在 OAuth 客户端与两个或更多授权服务器交互的场景中, 客户端必须防止混淆攻击。为了防止混淆攻击,客户端必须只处理 来自其向之发送相应请求的颁发者的重定向响应,并且该响应必须来自 发起该授权请求时使用的同一用户代理。¶
到客户端端点的重定向请求通常会产生一个由用户代理处理的 HTML 文档响应。如果 HTML 响应直接作为重定向请求的结果提供, 则 HTML 文档中包含的任何脚本都将以对重定向 URI 及其包含的 工件(例如授权码)的完全访问权限执行。此外,包含授权码的请求 URL 可能会在 HTTP Referer 标头中发送给页面中加载的任何嵌入图像、 样式表和其他元素。¶
客户端不应在重定向 URI 端点响应中包含任何第三方脚本 (例如第三方分析、社交插件、广告网络)。相反,它应从 URI 中提取工件,并再次将用户代理重定向到另一个端点, 且不暴露这些工件(无论是在 URI 中还是其他位置)。 如果包含第三方脚本,客户端必须确保自己的脚本 (用于从 URI 提取并移除凭据)首先执行。¶
只有在底层凭据的签发/注册和分发过程确保其机密性的情况下, 授权服务器才必须依赖客户端认证。¶
对于机密客户端,授权服务器可以接受任何满足其安全要求的 客户端认证形式(例如客户端密钥、公钥/私钥对)。¶
建议使用非对称(基于公钥)方法进行客户端认证,
例如 mTLS [RFC8705],或按照
[RFC7521]、[RFC7523]
及其更新 [I-D.ietf-oauth-rfc7523bis]
使用已签名 JWT(“Private Key JWT”)
(在 [OpenID.Connect] 中定义为
private_key_jwt 客户端认证方法)。
使用此类客户端认证方法时,授权服务器无需存储敏感的对称密钥,
这使这些方法对多种攻击更为稳健,并使客户端能够管理自己的密钥和
密钥轮换。¶
使用基于 JWT 的客户端认证时,客户端和授权服务器必须遵循
[I-D.ietf-oauth-rfc7523bis] 中关于
aud 值的更新指导。¶
当无法进行客户端认证时,授权服务器应采用其他方式来验证 客户端身份——例如要求注册客户端重定向 URI,或让资源所有者确认身份。 在请求资源所有者授权时,有效的重定向 URI 不足以验证客户端身份, 但可用于在获得资源所有者授权后,防止将凭据交付给假冒客户端。¶
客户端在每个请求中不得使用超过一种认证方法, 以防止关于哪个认证机制对请求具有权威性的冲突。¶
授权服务器必须考虑与未经认证客户端交互的安全影响, 并采取措施限制颁发给此类客户端的令牌的潜在暴露 (例如限制刷新令牌的生命周期)。¶
授权服务器与特定客户端身份关联的权限,必须取决于其对 客户端标识和客户端凭据生命周期管理整体过程的评估。 有关其他详细信息,请参见 第 7.2 节。¶
为了支持持有客户端密钥的机密客户端, 授权服务器必须支持客户端使用以下参数在请求正文内容中包含 客户端凭据:¶
这些参数只能在请求内容中传输,并且不得包含在请求 URI 中。¶
这也称为 client_secret_post,
如 [RFC7591] 的
第
2 节 中所定义。¶
例如,使用内容参数刷新访问令牌 (第 4.3 节)的请求 (额外换行仅用于显示目的):¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw¶
授权服务器可以支持 HTTP Basic 认证方案, 用于认证已颁发客户端密钥的客户端。¶
当使用
[RFC9110] 的
第
11 节
所定义的 HTTP Basic 认证方案向授权服务器认证时,
客户端标识符使用 附录
B 中的
application/x-www-form-urlencoded 编码算法进行编码,
并将编码后的值用作用户名;客户端密钥使用相同算法编码并用作密码。¶
这也称为 client_secret_basic,
如 [RFC7591] 的
第
2 节 中所定义。¶
例如(额外换行仅用于显示目的):¶
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3¶
注意:这种先对客户端标识符和密钥进行表单编码, 然后将编码后的值用作 HTTP Basic 认证用户名和密码的方法, 过去导致了许多互操作性问题。一些实现遗漏了编码步骤, 或决定只编码某些字符,或在验证凭据时忽略编码要求, 导致客户端不得不为其向各个授权服务器提交凭据的方式进行特殊处理。 在请求正文内容中包含凭据可以避免编码问题,并产生更具互操作性的实现。¶
由于客户端密钥认证方法涉及密码, 授权服务器必须保护任何使用该方法的端点免受暴力破解攻击。¶
授权服务器可以支持任何符合其安全要求的合适认证方案。 使用其他认证方法时,授权服务器必须定义客户端标识符 (注册记录)与认证方案之间的映射。¶
一些额外认证方法,例如 mTLS [RFC8705] 和 Private Key JWT([RFC7523]、 [I-D.ietf-oauth-rfc7523bis]) 定义在 “OAuth Token Endpoint Authentication Methods” 注册表中, 并且作为通用客户端认证方法可能很有用,而不仅限于保护令牌端点的特定用途。¶
授权过程使用两个授权服务器端点(HTTP 资源):¶
以及一个客户端端点:¶
重定向端点——由授权服务器用于通过资源所有者用户代理 将包含授权凭据的响应返回给客户端。¶
并非每种授权授予类型都会使用两个端点。 扩展授予类型可以根据需要定义其他端点。¶
令牌端点由客户端用于使用授予获得访问令牌, 例如 第 4 节 和 第 4.3 节 中描述的授予。¶
客户端获得令牌端点 URL 的方式超出本规范范围, 但该 URL 通常在服务文档中提供并在客户端开发期间配置, 或在授权服务器的元数据文档 [RFC8414] 中提供并在运行时以编程方式获取。¶
令牌端点 URL 不得包含片段组件, 并且可以包含查询字符串组件 附录 C.1。¶
客户端向令牌端点发出请求时必须使用 HTTP POST 方法。¶
授权服务器必须忽略发送到令牌端点的未识别请求参数。¶
发送时没有值的参数必须被视为已从请求中省略。本规范定义的 请求和响应参数不得包含超过一次。此要求也适用于扩展定义的参数, 除非该扩展对特定参数明确另有定义。¶
希望支持基于浏览器应用程序的授权服务器 (例如完全在客户端 JavaScript 中运行且无法访问支持性后端服务器的应用程序) 需要确保令牌端点支持必要的 CORS [WHATWG.CORS] 标头,以允许应用程序看到响应。 如果授权服务器向应用程序提供其他端点,例如元数据 URL、 动态客户端注册、撤销、自省、发现或用户信息端点, 这些端点也可能被基于浏览器的应用程序访问,并且也需要定义 CORS 标头以允许访问。 有关更多详细信息,请参见 [I-D.ietf-oauth-browser-based-apps]。¶
客户端通过在 HTTP 请求内容中使用 UTF-8 字符编码, 按 附录 C.2 的表单编码序列化格式发送以下参数,向令牌端点发出请求:¶
必需。客户端在特定令牌请求中使用的授予类型标识符。
本规范定义了值 authorization_code、
refresh_token 和 client_credentials。
授予类型决定令牌请求所需或支持的其他参数。
这些授予类型的详细信息在下文定义。¶
可选。当使用依赖该参数的客户端认证形式,
或 grant_type 要求标识公开客户端时,需要客户端标识符。¶
机密客户端必须按照 第 3.2.1 节 所述向授权服务器认证。¶
例如,客户端发出以下 HTTPS 请求 (额外换行仅用于显示目的):¶
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb &code_verifier=3641a2d12d66101249cdf7a79c000c1f8c05d2aafcf14bf146497bed¶
授权服务器必须:¶
进一步的特定授予类型处理规则适用,并在相应授予类型中指定。¶
如果访问令牌请求有效并已获授权, 授权服务器会颁发访问令牌和可选的刷新令牌。¶
如果客户端认证失败或无效, 授权服务器返回如 第 3.2.4 节 所述的错误响应。¶
授权服务器通过按照 附录 C.3 创建 HTTP 响应来颁发访问令牌
和可选刷新令牌,使用 [RFC8259] 定义的
application/json 媒体类型,并带有以下参数和 HTTP 200 (OK) 状态码:¶
必需。授权服务器颁发的访问令牌。¶
建议。一个 JSON 数字,表示访问令牌的生命周期
(以秒为单位)。例如,值 3600 表示访问令牌将在
生成响应后一小时过期。如果省略,授权服务器应通过其他方式提供
生命周期,或记录默认值。请注意,授权服务器可以提前使访问令牌过期,
客户端不得期望访问令牌在所提供的生命周期内一直有效。¶
可选。刷新令牌,可用于基于相应令牌请求中 传入的授予来获得新的访问令牌。¶
授权服务器应根据风险评估和自身策略决定是否向特定客户端 颁发刷新令牌。如果授权服务器决定不颁发刷新令牌, 客户端可以通过重新开始 OAuth 流程来获得新的访问令牌, 例如发起新的授权码请求。在这种情况下,授权服务器可以使用 cookie 和持久授权来优化用户体验。¶
如果颁发刷新令牌,这些刷新令牌必须绑定到资源所有者同意的 范围和资源服务器。这样做是为了防止合法客户端提升权限, 并降低刷新令牌泄露的影响。¶
这些参数按照 附录 C.3 的描述序列化为 JavaScript Object Notation (JSON) 结构。¶
授权服务器必须在任何包含令牌、凭据或其他敏感信息的响应中
包含 HTTP Cache-Control 响应标头字段
(参见 [RFC9111] 的
第
5.2 节),其值为 no-store。¶
例如:¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value"
}
¶
客户端必须忽略响应中未识别的值名称。 从授权服务器接收的令牌和其他值的大小保持未定义。 客户端应避免对值大小作出假设。授权服务器应记录其颁发的任何值的大小。¶
授权服务器以 HTTP 400 (Bad Request) 状态码响应 (除非另有指定),并在响应中包含以下参数:¶
必需。来自以下内容的单个 ASCII [USASCII] 错误代码:¶
请求缺少必需参数,
包含不受支持的参数值(授予类型除外),
重复参数,包含多个凭据,使用超过一种机制认证客户端,
在授权请求中未发送 code_challenge 的情况下包含
code_verifier,或在其他方面格式错误。¶
客户端认证失败(例如未知客户端、
未包含客户端认证,或不受支持的认证方法)。
授权服务器可以返回 HTTP 401 (Unauthorized) 状态码,
以指示支持哪些 HTTP 认证方案。如果客户端尝试通过
Authorization 请求标头字段进行认证,
授权服务器必须以 HTTP 401 (Unauthorized) 状态码响应,
并包含与客户端所用认证方案匹配的
WWW-Authenticate 响应标头字段。¶
所提供的授权授予 (例如授权码、资源所有者凭据)或刷新令牌无效、 已过期、已撤销,与授权请求中使用的重定向 URI 不匹配, 或已颁发给另一个客户端。¶
经认证的客户端未被授权使用此授权授予类型。¶
授权服务器不支持该授权授予类型。¶
所请求范围无效、未知、格式错误, 或超出资源所有者授予的范围。¶
error 参数的值不得包含
集合 %x20-21 / %x23-5B / %x5D-7E 之外的字符。¶
可选。人类可读的 ASCII
[USASCII] 文本,
提供额外信息,用于帮助客户端开发者理解发生的错误。
error_description 参数的值不得包含
集合 %x20-21 / %x23-5B / %x5D-7E 之外的字符。¶
可选。标识一个包含错误相关信息的人类可读网页的 URI,
用于向客户端开发者提供关于该错误的额外信息。
error_uri 参数的值必须符合 URI-reference 语法,
因此不得包含集合 %x21 / %x23-5B / %x5D-7E 之外的字符。¶
这些参数使用 application/json 媒体类型包含在
HTTP 响应内容中,如 附录 C.3 所定义。¶
例如:¶
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_request"
}
¶
客户端通过向资源服务器提交访问 令牌来访问受保护资源。资源服务器必须验证 访问令牌,并确保它尚未过期,且其范围 覆盖所请求的资源。资源服务器用于验证访问令牌的 方法超出本规范范围,但通常涉及资源服务器与 授权服务器之间的交互或协调。例如,当资源服务器和 授权服务器位于同处或属于同一系统时, 它们可以共享数据库或其他存储;当两个组件 独立运营时,它们可以使用 Token Introspection [RFC7662] 或结构化访问令牌格式,例如 JWT [RFC9068]。¶
本节定义了在资源请求中向资源服务器发送承载令牌的 两种方法。客户端必须使用以下定义的两种方法之一, 并且在每个请求中不得使用超过一种方法来传输令牌。¶
特别是,客户端不得在 URI 查询参数中发送访问令牌, 资源服务器必须忽略 URI 查询参数中的访问令牌。¶
当在 HTTP 请求内容中发送访问令牌时,
客户端使用 access_token 参数将访问令牌添加到请求内容中。
除非满足以下所有条件,否则客户端不得使用此方法:¶
HTTP 请求包含设置为
application/x-www-form-urlencoded 的 Content-Type
标头字段。¶
内容遵循 URL 现行标准
[WHATWG.URL] 定义的
application/x-www-form-urlencoded 内容类型编码要求。¶
HTTP 请求内容是单部分的。¶
HTTP 请求方法必须是内容具有已定义语义的方法。
特别是,这意味着不得使用 GET
方法。¶
内容可以包含其他特定于请求的参数,在这种情况下,
access_token 参数必须使用 & 字符
(ASCII 代码 38)与特定于请求的参数正确分隔。¶
例如,客户端使用传输层安全发出以下 HTTP 请求:¶
POST /resource HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded access_token=mF_9.B5f-4.1JqM¶
除非在参与客户端无法访问
Authorization 请求标头字段的应用上下文中,
否则不应使用 application/x-www-form-urlencoded 方法。
资源服务器可以支持此方法。¶
在收到访问令牌后,资源服务器必须检查 访问令牌尚未过期,已被授权访问所请求的资源, 以适当范围颁发,并满足资源服务器访问受保护资源的 其他策略要求。¶
访问令牌通常分为两类:引用令牌或 自编码令牌。 引用令牌可以通过查询授权服务器或在令牌数据库中 查找令牌来验证,而自编码令牌 将授权信息包含在可由资源服务器提取的加密和/或签名字符串中。¶
Token Introspection [RFC7662] 定义了一种查询授权服务器以检查访问令牌有效性的 标准化方法。¶
JWT Profile for Access Tokens [RFC9068] 定义了一种在令牌字符串中编码信息的 标准化方法。¶
如果资源访问请求失败,资源服务器应告知 客户端该错误。错误响应的细节由特定令牌类型确定, 例如 第 5.3.2 节 中对承载令牌的 描述。¶
如果受保护资源请求不包含认证
凭据,或不包含能够访问
受保护资源的访问令牌,则资源服务器必须包含 HTTP
WWW-Authenticate 响应标头字段;它也可以在
响应其他条件时包含该字段。WWW-Authenticate 标头
字段使用 HTTP/1.1 [RFC7235] 定义的框架。¶
此令牌类型的所有质询都必须使用 auth-scheme
值 Bearer。该方案后必须跟随一个或多个
auth-param 值。本规范为此令牌类型使用或定义的
auth-param 属性如下。也可以使用其他 auth-param
属性。¶
可以包含 realm 属性,
以 HTTP/1.1 [RFC7235]
中描述的方式指示
保护范围。realm 属性不得出现超过一次。¶
scope 属性定义于
第 1.4.1 节。
scope 属性是以空格分隔的区分大小写范围值列表,
指示访问所请求资源所需的访问令牌范围。
scope 值由实现定义;没有集中注册表;
允许值由授权服务器定义。scope 值的顺序
不重要。在某些情况下,请求具有足够访问范围的新访问令牌
以利用受保护资源时,会使用 scope 值。
scope 属性的使用是可选的。
scope 属性不得出现超过一次。
scope 值旨在供程序使用,并不意味着显示给最终用户。¶
下面给出两个示例 scope 值;它们分别取自 OpenID Connect [OpenID.Messages] 和 Open Authentication Technology Committee (OATC) Online Multimedia Authorization Protocol [OMAP] OAuth 2.0 用例:¶
scope="openid profile email" scope="urn:example:channel=HBO&urn:example:rating=G,PG-13"¶
如果受保护资源请求包含访问
令牌并且认证失败,资源服务器应包含 error
属性,以向客户端提供访问
请求被拒绝的原因。参数值在
第
5.3.2 节 中描述。¶
资源服务器可以包含
error_description 属性,以向开发者提供人类可读的
说明,该说明不应显示给最终用户。¶
资源服务器可以包含
error_uri 属性,其值为一个绝对 URI,
用于标识解释错误的人类可读网页。¶
error、error_description 和
error_uri 属性不得
出现超过一次。¶
scope 属性的值(在
附录 A.4 中指定)
不得包含用于表示 scope 值的集合 %x21 / %x23-5B
/ %x5D-7E 之外的字符,以及 scope 值之间分隔符使用的 %x20
之外的字符。error 和
error_description
属性的值(在 附录
A.7 和 附录
A.8 中指定)不得
包含集合 %x20-21 / %x23-5B / %x5D-7E 之外的字符。
error_uri 属性的值(在
附录 A.9 中指定)
必须符合 URI-reference 语法,因此不得
包含集合 %x21 / %x23-5B / %x5D-7E 之外的字符。¶
当请求失败时,资源服务器使用适当的 HTTP 状态码(通常为 400、401、403 或 405)进行响应, 并在响应中包含以下错误代码之一:¶
请求缺少必需参数,包含不受支持的参数或 参数值,重复相同参数,使用超过一种方法包含访问 令牌,或在其他方面格式错误。资源服务器应 以 HTTP 400 (Bad Request) 状态码响应。¶
提供的访问令牌已过期、已撤销、 格式错误,或因其他原因无效。资源服务器应以 HTTP 401 (Unauthorized) 状态码响应。客户端可以 请求新的访问令牌并重试受保护资源 请求。¶
该请求需要比授予客户端并由访问令牌表示的
范围所提供的权限(范围)更高的权限。
资源服务器应以 HTTP
403 (Forbidden) 状态码响应,并可以包含 scope
属性,其值为访问受保护
资源所需的范围。¶
扩展可以定义额外错误代码,或指定返回上述错误代码的 其他情形。¶
如果请求缺少任何认证信息(例如, 客户端不知道认证是必要的,或尝试使用不受支持的认证方法), 资源服务器不应包含错误代码或其他错误信息。¶
例如:¶
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="example"¶
以及在响应使用已过期访问令牌进行认证尝试的 受保护资源请求时:¶
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"
¶
访问令牌类型可以通过以下两种方式之一来定义: 注册到 Access Token Types 注册表中(遵循 [RFC6749] 的 第 11.1 节 中的程序),或使用唯一的绝对 URI 作为其名称。¶
[RFC6750] 在 [RFC6749] 的 第 11.4 节 中建立了一个通用注册表,供 OAuth 令牌认证方案共享错误值。¶
主要为 OAuth 令牌认证设计的新认证方案应定义 一种向客户端提供错误状态码的机制,其中允许的错误值 注册在本规范建立的错误注册表中。¶
此类方案可以将有效错误代码集合限制为
已注册值的子集。如果错误代码使用命名参数返回,
则参数名称应为 error。¶
其他能够用于 OAuth 令牌认证, 但并非主要为此目的设计的方案,也可以以相同方式 将其错误值绑定到该注册表。¶
新的认证方案也可以选择指定使用
error_description 和 error_uri 参数,
以与本规范中的用法相平行的方式返回错误信息。¶
类型名称必须符合
type-name ABNF。如果类型定义包含新的 HTTP
认证方案,则类型名称应与 HTTP 认证方案名称相同
(如 [RFC2617] 所定义)。令牌类型
example 保留用于示例。¶
type-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA¶
使用 URI 名称的类型应限于供应商特定的 实现,这些实现并非普遍适用,并且特定于其被使用的 资源服务器实现细节。¶
所有其他类型都必须注册。¶
用于授权端点或令牌端点的新请求或响应参数, 按照 [RFC6749] 的 第 11.2 节 中的程序,在 OAuth Parameters 注册表中定义并注册。¶
参数名称必须符合 param-name ABNF, 并且参数值语法必须被明确定义(例如,使用 ABNF, 或引用现有参数的语法)。¶
param-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA¶
未注册的供应商特定参数扩展,如果并非普遍适用, 且特定于其被使用的授权服务器实现细节,则应 使用不太可能与其他已注册值冲突的供应商特定前缀 (例如,以 'companyname_' 开头)。¶
用于授权端点的新响应类型按照 [RFC6749] 的 第 11.3 节 中的程序,在 Authorization Endpoint Response Types 注册表中定义并注册。响应类型 名称必须符合 response-type ABNF。¶
response-type = response-name *( SP response-name ) response-name = 1*response-char response-char = "_" / DIGIT / ALPHA¶
如果响应类型包含一个或多个空格字符(%x20), 则它会作为以空格分隔的值列表进行比较,其中 值的顺序无关紧要。只能注册一种值顺序, 该顺序涵盖同一组值的所有其他排列。¶
例如,一个扩展可以定义并注册
code other_token
响应类型。一旦注册,同一组合不能注册为
other_token code,但两个值都可以用于
表示同一响应类型。¶
在协议扩展(即访问令牌类型、 扩展参数或扩展授予类型)需要与授权码授予错误 响应(第 4.1.2.1 节)、令牌错误响应(第 3.2.4 节)或 资源访问错误响应(第 5.3 节)一起使用额外错误代码的情况下,可以 定义此类错误代码。¶
如果扩展错误代码与之结合使用的扩展是 已注册访问令牌类型、已注册端点参数或 扩展授予类型,则必须注册这些错误代码(遵循 [RFC6749] 的 第 11.4 节 中的程序)。与未注册扩展一起使用的错误代码 可以注册。¶
错误代码必须符合 error ABNF,并且在可能时应以
标识性名称作为前缀。例如,标识扩展参数
example 设置为无效值的错误应命名为
example_invalid。¶
error = 1*error-char error-char = %x20-21 / %x23-5B / %x5D-7E¶
作为一个灵活且可扩展的框架,OAuth 的安全 考虑取决于许多因素。以下各节 为实现者提供安全指南,重点关注 第 2.1 节 中描述的三个客户端配置文件:Web 应用程序、 基于浏览器的应用程序和原生应用程序。¶
全面的 OAuth 安全模型和分析,以及 协议设计背景,由 [RFC6819] 和 [RFC9700] 提供。¶
以下列表列出了针对使用某种形式令牌的协议的若干常见威胁。 该威胁列表基于 NIST Special Publication 800-63 [NIST800-63]。¶
攻击者可能生成伪造的 访问令牌,或修改现有令牌的内容(例如认证或 属性声明),导致资源 服务器向客户端授予不适当的访问权限。例如, 攻击者可能修改令牌以延长有效期; 恶意客户端可能修改断言,以获得其不应查看的信息访问权限。¶
通过使用数字签名保护访问令牌的内容, 并遵循签名密钥管理的最佳实践(例如定期密钥轮换), 可以缓解大量威胁。¶
或者,承载令牌可以包含对 授权信息的引用,而不是直接编码该信息。 使用引用可能需要资源服务器与授权服务器之间的额外交互, 以将引用解析为授权信息。此类交互机制 未由本规范定义,但 Token Introspection [RFC7662] 定义了一种这样的机制。¶
本文档不指定访问令牌的编码或内容; 因此,有关保证访问令牌完整性保护手段的详细建议 超出本规范范围。 JSON Web Token Profile for Access Tokens [RFC9068] 中描述了 访问令牌的一种编码和签名机制示例。¶
为了处理访问令牌重定向,授权 服务器在令牌中包含预期接收方(受众)的身份非常重要, 通常是单个资源服务器(或资源服务器列表)。 也建议将令牌的使用限制到特定范围。¶
第 1.5 节 提供了相关信息, 用于防止访问令牌泄露,并为客户端、资源服务器和授权服务器之间的 通信提供机密性和完整性。¶
客户端在向受保护资源发出请求时 必须验证 TLS 证书链。未能这样做可能使 DNS 劫持攻击能够窃取 令牌并获得非预期访问权限。¶
客户端在使用 承载令牌发出请求时,必须始终使用 TLS (https) 或等效的传输安全。未能这样做会使令牌暴露于 诸多攻击之下,可能让攻击者获得非预期访问权限。¶
授权服务器应颁发 短生命周期承载令牌,尤其是在向运行于 Web 浏览器或其他 可能发生信息泄露的环境中的客户端颁发令牌时。 使用短生命周期承载令牌可以降低令牌被 泄露的影响。¶
授权服务器应颁发包含受众限制的承载令牌, 将其使用范围限定到预期资源服务器或 资源服务器集合。¶
承载令牌不得 在页面 URL 中传递(例如作为查询字符串参数)。 相反,承载令牌应在采取了机密性措施的 HTTP 消息标头或 消息正文中传递。浏览器、Web 服务器和其他软件可能无法 充分保护浏览器历史记录、Web 服务器日志和其他 数据结构中的 URL。如果承载令牌在页面 URL 中传递, 攻击者可能能够从历史数据、日志或 其他不安全位置窃取它们。¶
与访问令牌关联的权限应限制为特定应用程序或用例 所需的最低权限。这可以防止客户端超出资源所有者授权的权限。 它还可以防止用户超出相应安全策略授权的 权限。权限限制也有助于降低访问令牌泄露的影响。¶
特别是,访问令牌应限制到某些
资源服务器(受众限制),最好是单个资源
服务器。为了实现这一点,授权服务器将
访问令牌与某些资源服务器相关联,并且每个资源
服务器都有义务针对每个请求验证随该请求发送的访问
令牌是否旨在用于该特定
资源服务器。如果不是,资源服务器必须拒绝服务
相应请求。客户端和授权服务器可以分别利用本文档和
[RFC8707] 中指定的
scope 或 resource 参数,
来确定其希望访问的资源服务器。¶
此外,访问令牌应限制到资源服务器或资源上的
某些资源和操作。为了实现这一点,
授权服务器将访问令牌与相应资源和操作相关联,
并且每个资源服务器都有义务针对每个请求验证随该请求
发送的访问令牌是否旨在用于对特定资源执行
该特定操作。如果不是,资源服务器必须拒绝
服务相应请求。客户端和授权服务器可以利用
[RFC9396] 中指定的参数
scope 和
authorization_details 来确定这些资源和/或操作。¶
根据客户端注册和凭据生命周期管理的整体过程, 这可能会影响授权服务器对特定客户端的信心水平。¶
例如,对动态注册客户端的认证并不证明客户端的身份, 它只确保向授权服务器重复发出的请求来自同一个客户端实例。 此类客户端在允许请求的范围方面可能受到限制, 或可能有其他限制,例如更短的令牌生命周期。¶
相比之下,如果存在一个已注册应用,其开发者身份 已验证、已签署合同,并被颁发仅在安全后端服务中使用的 客户端密钥,则授权服务器可能允许此客户端请求更敏感的范围 或被颁发生命周期更长的令牌。¶
如果机密客户端的凭据被窃取, 恶意客户端可以冒充该客户端并获得对 受保护资源的访问权限。¶
授权服务器应强制执行明确的资源所有者 认证,并向资源所有者提供有关客户端以及所请求授权范围和生命周期的信息。 由资源所有者在当前客户端的上下文中审查这些信息,并授权或拒绝请求。¶
授权服务器不应在没有认证客户端或依赖其他措施以 确保重复请求来自原始客户端而非冒充者的情况下, 自动处理重复的授权请求(没有主动的资源所有者交互)。¶
如上所述,授权 服务器不应在没有用户同意或交互的情况下自动处理授权请求, 除非能够确保客户端的身份。这包括用户先前已批准给定客户端 ID 授权请求的情况——除非能够证明客户端身份, 否则该请求应按没有先前请求被批准的方式处理。¶
授权服务器可以接受诸如已声明的
https 方案重定向等措施作为身份证明。
某些操作系统可能提供其他平台特定的身份功能,
也可以视情况接受。¶
客户端应请求具有必要最小范围的访问令牌。 授权服务器在选择如何满足所请求范围时应考虑客户端身份, 并可以颁发范围少于请求范围的访问令牌。¶
与访问令牌关联的权限应限制为 特定应用程序或用例所需的最低权限。这 可以防止客户端超出资源所有者授权的权限。 它还可以防止用户超出相应安全策略授权的权限。 权限限制也有助于降低访问令牌泄露的影响。¶
特别是,访问令牌应限制到某些
资源服务器(受众限制),最好是单个资源
服务器。为了实现这一点,授权服务器将
访问令牌与某些资源服务器相关联,并且每个资源
服务器都有义务针对每个请求验证随该请求发送的访问
令牌是否旨在用于该特定
资源服务器。如果不是,资源服务器必须拒绝服务
相应请求。客户端和授权服务器可以分别利用
[RFC8707] 中指定的
scope 或 resource 参数,
来确定其希望访问的资源服务器。¶
资源服务器可能基于访问令牌为之颁发的
资源所有者身份,或基于客户端凭据授予中的客户端身份作出访问控制决策。
如果这两种选项都可能存在,则根据实现细节,
客户端身份可能会被误认为资源所有者身份。例如,
如果客户端在向授权服务器注册时能够选择自己的
client_id,恶意客户端可能将其设置为标识最终用户的值
(例如,如果使用 OpenID Connect,则为 sub 值)。
如果资源服务器无法正确区分颁发给客户端的访问令牌和
颁发给最终用户的访问令牌,则客户端随后可能能够访问最终用户的资源。¶
如果授权服务器对客户端 ID 和用户
标识符使用公共命名空间,导致资源服务器无法区分由资源所有者授权的访问
令牌和由客户端自身授权的访问令牌,则授权服务器不应允许客户端影响其
client_id 或任何其他可能导致与真实资源所有者混淆的 Claim。
在无法避免这种情况时,授权服务器必须为资源服务器提供其他方式,
以区分这两种类型的访问令牌。¶
授权服务器必须防止攻击者猜测访问 令牌、授权码、刷新令牌、资源所有者 密码和客户端凭据。¶
攻击者猜测生成的令牌(以及其他不打算由最终用户处理的 凭据)的概率必须小于或等于 2^(-128),并且应 小于或等于 2^(-160)。¶
授权服务器必须利用其他方式保护 供最终用户使用的凭据。¶
此协议及类似协议的广泛部署可能导致最终用户 对被重定向到要求其输入密码的网站这一做法习以为常。 如果最终用户在输入凭据前不谨慎验证这些网站的真实性, 攻击者就可能利用这种做法窃取资源所有者的密码, 以及其他可被钓鱼获取的凭据,例如 OTP。¶
服务提供商应尝试教育最终用户了解网络钓鱼攻击带来的风险, 并应提供使最终用户易于确认其站点真实性的机制, 例如使用抗钓鱼认证器,因为抗钓鱼认证器只有在平台成功验证 站点来源后,才会向用户提供用于登录某个站点的凭据。 客户端开发者应考虑其与用户代理交互方式(例如外部、嵌入式)的 安全影响,以及最终用户验证授权服务器真实性的能力。¶
攻击者可能尝试向受害者设备上合法客户端的重定向 URI 注入请求,例如导致客户端访问攻击者控制下的资源。 这是称为跨站请求伪造(CSRF)的攻击的一种变体。¶
传统对策是客户端在 state 参数中传递随机值,
也称为 CSRF Token,该值按描述将请求与重定向 URI
绑定到用户代理会话。
此对策在 [RFC6819] 的
第 5.3.5
节
中有详细描述。code_verifier 参数或
OpenID Connect nonce 值也提供相同保护。¶
当使用 code_verifier 而不是 state 或
nonce 进行 CSRF 保护时,需要注意:¶
客户端必须确保 AS 支持客户端
打算使用的
code_challenge_method。
如果授权服务器不支持请求的方法,
则必须改用 state 或 nonce 进行 CSRF 保护。¶
如果 state 用于携带应用程序状态,并且
其内容的完整性是一个关注点,则客户端必须保护 state
免受篡改和交换。这可以通过将
state 的内容绑定到浏览器会话和/或使用已签名/加密的
state 值 [I-D.bradley-oauth-jwt-encoded-state] 来实现。¶
因此,AS 必须提供一种方式来检测其支持的代码挑战 方法,要么通过符合 [RFC8414] 的 AS 元数据, 要么提供特定于部署的方式来确保或确定支持。¶
如 [RFC6819] 的 第 4.4.1.9 节 所述, 授权 请求容易受到点击劫持攻击,也称为用户 界面重绘攻击。在此类攻击中,攻击者将 授权端点用户界面嵌入到无害上下文中。 用户以为正在与该上下文交互,例如 点击按钮,却无意中与授权 端点用户界面交互。也可以实现相反效果: 用户以为正在与授权端点交互, 却可能无意中将密码输入到攻击者提供的、 覆盖在原始用户界面上的输入字段中。点击劫持 攻击可以设计得让用户几乎难以察觉, 例如使用几乎不可见的 iframe 覆盖在 其他元素之上。¶
攻击者可以利用此向量获取用户的认证 凭据,更改授予客户端的访问范围, 并可能访问用户的资源。¶
授权服务器必须防止点击劫持攻击。
[RFC6819] 中描述了多种
对策,包括使用 X-Frame-Options HTTP 响应标头字段和
frame-busting JavaScript。除此之外,授权服务器还应
使用 Content Security Policy (CSP) level 2 [CSP-2] 或更高版本。¶
为了有效,CSP 必须用于授权端点,并且 在适用时用于其他用于认证用户和 授权客户端的端点(例如设备授权端点、登录 页面、错误页面等)。这可以防止支持 CSP 的用户代理中 未授权来源的框架嵌入。客户端可以允许被 其重定向端点所用来源之外的某些其他来源嵌入。 因此,授权服务器应允许 管理员为特定客户端配置允许的来源, 和/或允许客户端动态注册这些来源。¶
使用 CSP 允许授权服务器在单个响应标头字段中
指定多个来源,并使用灵活模式约束这些来源
(详见 [CSP-2])。
该标准第 2 级提供了一种稳健机制,可通过使用
限制框架来源的策略(使用 frame-ancestors)
以及限制允许在 HTML 页面上执行的脚本来源的策略
(使用 script-src),来防止点击劫持。
以下列表显示了此类策略的非规范性示例:¶
HTTP/1.1 200 OK Content-Security-Policy: frame-ancestors https://ext.example.org:8000 Content-Security-Policy: script-src 'self' X-Frame-Options: ALLOW-FROM https://ext.example.org:8000 ...¶
由于某些用户代理不支持 [CSP-2],此技术 应与其他技术结合使用,包括 [RFC6819] 中描述的技术,除非授权服务器明确不支持此类旧版用户代理。 即使在这种情况下,仍应采用额外的 对策。¶
当应用程序未经过滤地使用输入或其他外部 变量,并导致应用程序逻辑被修改时,就会发生注入攻击。 这可能允许攻击者获得对应用程序设备或其数据的访问权限, 造成拒绝服务,或引入范围广泛的恶意副作用。¶
授权服务器和客户端必须将接收到的参数视为
潜在恶意的外部输入,并应用适当保护,
特别是 state 和 redirect_uri 参数的值。¶
开放重定向器是将用户浏览器 转发到从查询参数获得的任意 URI 的端点。 此类端点有时会被实现,例如在用户随后被重定向到外部网站前 显示消息,或在用户被中断(例如登录提示)之前, 将用户重定向回其原本打算访问的 URL。¶
当 AS 或客户端具有开放 重定向器时,可能发生以下攻击。¶
客户端不得暴露开放重定向器。 攻击者可能使用开放重定向器生成指向客户端的 URL, 并利用它们外泄授权码,如 [RFC9700] 的 第 4.1.1 节 所述。 另一种滥用情况是生成看似指向客户端的 URL。 这可能诱骗用户信任该 URL 并在浏览器中访问它。 这可被滥用于网络钓鱼。¶
为了防止开放重定向,客户端应仅在 目标 URL 位于白名单中,或请求的来源和完整性可被认证时 才进行重定向。OWASP [owasp_redir] 描述了防范开放重定向的对策。¶
在某些部署中,包括利用负载均衡器的部署, 到资源服务器的 TLS 连接会在实际提供资源的 服务器之前终止。这可能使令牌在 TLS 连接终止的 前端服务器与提供资源的后端服务器之间 不受保护。在此类部署中,必须采用充分措施来确保 前端服务器与后端服务器之间访问令牌的机密性; 对令牌加密就是一种可能措施。¶
混淆是一种针对 OAuth 客户端与 两个或更多授权服务器交互,且至少一个授权 服务器受攻击者控制的场景的攻击。例如,如果攻击者使用动态注册 将客户端注册到其自己的授权服务器,或者如果某个授权服务器 被攻破,就可能出现这种情况。¶
当 OAuth 客户端只能与一个授权服务器交互时, 不需要混淆防御。然而,在 OAuth 客户端与两个或更多 授权服务器交互的场景中,客户端必须防止混淆攻击。 以下讨论两种不同方法。¶
对于两种防御,客户端都必须针对每个授权请求存储 其发送授权请求到的颁发者,将此信息绑定到 用户代理,并检查授权响应是否来自 正确的颁发者。客户端必须确保后续访问令牌请求 (如适用)发送到同一颁发者。颁发者通过相关 元数据作为授权端点和令牌端点组合的抽象标识符, 这些端点将在流程中使用。如果颁发者标识符 不可用,例如既未使用 OAuth 2.0 Authorization Server Metadata [RFC8414] 也未使用 OpenID Connect Discovery [OpenID.Discovery],则可以改用该元组的其他唯一标识符 或该元组本身。为简化表述, 下文将此类特定于部署的标识符归入颁发者(或 颁发者标识符)之下。¶
注意:仅存储授权服务器 URL 不足以识别 混淆攻击。攻击者可能将未被攻破的 AS 的授权端点 URL 声明为 “他们的” AS URL,但将令牌端点声明在其控制之下。¶
有关几种混淆攻击类型的详细描述, 请参见 [RFC9700] 的 第 4.4 节。¶
这种防御要求授权服务器在授权响应中向客户端发送其 颁发者标识符。收到授权 响应时,客户端必须将收到的颁发者标识符与存储的 颁发者标识符进行比较。如果不匹配,客户端必须中止 交互。¶
可以通过不同方式将此颁发者标识符传输 给客户端:¶
当使用 OpenID Connect,并且在授权
响应中返回 ID Token 时,客户端可以评估 ID Token 中的
iss claim。¶
在两种情况下,iss 值都必须按照
[RFC9207] 进行评估。¶
虽然这种防御可能需要使用额外参数来传输 颁发者信息,但它是一种稳健且相对简单的混淆防御。¶
对于这种防御,客户端必须为其交互的每个 颁发者使用不同的重定向 URI。¶
客户端必须通过将颁发者的不同重定向 URI 与接收授权响应的 URI 进行比较,检查授权响应是否来自正确 的颁发者。如果不匹配,客户端必须中止流程。¶
虽然这种防御建立在现有 OAuth 功能之上, 但在客户端只为使用许多不同颁发者而注册一次的场景中 (如某些开放银行方案)无法使用,并且由于与 客户端注册紧密集成,自动部署更加困难。¶
此外,攻击者可能能够通过使用客户端分配给攻击者 AS 的重定向 URI,在“诚实的” AS 处注册一个新客户端, 从而绕过这种防御提供的保护。攻击者随后可以按上述方式运行 攻击,将客户端 ID 替换为其新创建客户端的客户端 ID。¶
因此,只有在其他选项不可用时才应使用这种防御。¶
原生应用程序是安装并执行在资源所有者所用设备上的客户端 (即桌面应用程序或原生移动应用程序)。原生应用程序需要对 与安全、平台能力以及整体最终用户体验相关的问题 给予特殊考虑。¶
本节中的指南主要是在原生移动应用的上下文中给出, 而不是桌面应用。与这里描述的 OAuth 流程相关的、 提供给应用开发者的能力方面,原生移动平台 比桌面平台更加成熟。虽然该指南主要聚焦于移动应用, 但其中许多内容通常也可适用于桌面应用。¶
授权端点要求客户端与资源所有者的用户代理之间 进行交互。当前最佳实践是在外部用户代理 (通常是浏览器)中执行 OAuth 授权请求, 而不是在嵌入式用户代理(例如使用 web-view 实现的 用户代理)中执行。¶
原生应用程序可以通过几种不同方式 捕获来自授权服务器的响应,每种方式具有不同的安全属性。 例如,使用带有“应用声明 URL”或自定义 URL 方案的重定向 URI, 该方案注册到操作系统以调用客户端作为处理程序; 手动复制和粘贴凭据;运行本地 Web 服务器; 安装用户代理扩展;或者提供一个重定向 URI, 该 URI 标识客户端控制下的服务器托管资源, 而该资源随后使响应可供原生应用程序使用。¶
以前,原生应用常用嵌入式用户代理 (通常使用 web-view 实现)来进行 OAuth 授权请求。 这种方法有许多缺点,包括宿主应用能够复制用户凭据和 cookie, 以及用户需要在每个应用中从头开始认证。有关使用嵌入式用户代理 进行 OAuth 的缺点的更深入分析,请参见 第 8.5.1 节。¶
使用系统浏览器的原生应用授权请求更加安全, 并且可以利用用户在设备上的认证状态。能够使用浏览器中 现有的认证会话可实现单点登录,因为用户每次使用新应用时 不需要向授权服务器重新认证(除非授权服务器策略要求)。¶
无需改变 OAuth 协议本身,就可以支持原生应用与浏览器之间的 授权流程,因为 OAuth 授权请求和响应已经以 URI 的形式定义。这涵盖了可用于应用间通信的 URI。 一些假定所有客户端都是机密 Web 客户端的 OAuth 服务器实现 将需要增加对公开原生应用客户端以及它们所使用的 重定向 URI 类型的理解,以支持此最佳实践。¶
作为分发给多个用户的应用的一部分而静态包含的密钥
不是机密密钥,因为某个用户可以检查自己的副本并获知共享密钥。
因此,授权服务器不得要求原生应用客户端
使用共享密钥进行客户端认证,因为这除了客户端标识之外
没有任何价值,而客户端标识已经由 client_id 请求参数提供。¶
仍要求原生应用客户端使用静态包含的共享密钥的 授权服务器,必须将该客户端视为公开客户端 (如 第 2.1 节 中所定义),并且 不接受该密钥作为客户端身份的证明。没有 额外措施时,此类客户端会受到客户端冒充攻击 (参见 第 7.3.1 节)。¶
除非使用类似 Dynamic Client Registration [RFC7591] 的机制来为 每个实例配置凭据,否则原生应用被归类为公开客户端, 如 第 2.1 节 中所定义,并且必须作为此类客户端向授权服务器注册。 授权服务器必须在客户端注册详情中记录客户端类型, 以便相应地识别和处理请求。¶
草案规范 [I-D.ietf-oauth-attestation-based-client-auth] 定义了一种机制,原生应用可以使用该机制获得 与密钥绑定的证明,以向授权服务器或资源服务器认证。 这可以为移动应用的身份提供更高保证级别。¶
正如 Web 上的 OAuth 使用 URI 来发起 授权请求并将授权响应返回给请求网站一样, 原生应用也可以使用 URI 在设备浏览器中发起授权请求, 并将响应返回给请求的原生应用。¶
通过采用 Web 上用于 OAuth 的相同方法, Web 上所见的好处(例如单点登录会话的可用性以及 独立认证上下文的安全性)同样可在原生应用上下文中获得。 重用相同方法还通过依赖基于标准的 Web 流程来 降低实现复杂性并提高互操作性,而这些流程不特定于 某个平台。¶
原生应用必须使用外部用户代理来执行 OAuth 授权请求。这通过在浏览器中打开授权请求 (详见 第 8.3 节) 并使用会将授权响应返回给原生应用的重定向 URI (定义于 第 8.4 节) 来实现。¶
嵌入式用户代理在技术上是授权原生应用的一种可行方法。 根据定义,这些嵌入式用户代理对于授权服务器的第三方使用而言并不安全, 因为托管嵌入式用户代理的应用可以访问用户完整的认证凭据, 而不仅仅是原本打算授予该应用的 OAuth 授权授予。 它们通常也会被操作系统沙箱化,并且依赖 Web 来源的 WebAuthn 等机制会被禁用。¶
在典型的基于 web-view 的嵌入式用户代理实现中, 宿主应用可以记录登录表单中输入的每一次按键, 以捕获用户名和密码,自动提交表单以绕过用户同意, 并复制会话 cookie,然后使用它们以用户身份执行 已认证操作。¶
即使由与授权服务器同属一方的可信应用使用, 嵌入式用户代理也违反最小权限原则,因为它们可以访问 比自身所需更强大的凭据,从而可能扩大攻击面。¶
鼓励用户在没有通常地址栏和浏览器所具有的 可见证书验证功能的嵌入式用户代理中输入凭据, 会使用户无法知道自己是否正在登录合法站点;即使确实是, 这也会训练他们认为在先不验证站点的情况下输入凭据是可以接受的。¶
除安全问题外,嵌入式用户代理不会与其他应用或浏览器 共享认证状态,这要求用户为每次授权请求都重新登录, 通常被认为是一种较差的用户体验。¶
发起授权请求的原生应用对用户界面具有 很大控制权,并且可能呈现一个伪造的外部用户代理, 即将嵌入式用户代理伪装成外部用户代理。¶
当所有善意行为者都使用外部用户代理时, 其优势在于安全专家能够检测恶意行为者, 因为任何伪造外部用户代理的人都可被证明是恶意的。 另一方面,如果善意与恶意行为者都使用嵌入式用户代理, 恶意行为者不需要伪造任何东西,从而更难被检测。 一旦检测到恶意应用,可能可以利用这些知识 在恶意软件扫描软件中将该应用签名列入黑名单, 采取移除措施(对于通过应用商店分发的应用), 以及其他步骤来降低该恶意应用的影响和传播。¶
授权服务器也可以直接防范伪造的外部 用户代理,方法是要求一种仅真正外部用户代理可用的认证因素。¶
在使用应用内浏览器标签页时特别关注安全的用户 也可以采取额外步骤,从应用内浏览器标签页中 在完整浏览器中打开请求,并在那里完成授权, 因为大多数应用内浏览器标签页模式的实现都提供此功能。¶
如果恶意应用能够将自己配置为操作系统中
https 方案 URI 的默认处理程序,
它就能够拦截使用默认浏览器的授权请求,
并滥用这种信任位置达到恶意目的,例如对用户进行网络钓鱼。¶
这种攻击并不限于 OAuth;以这种方式配置的恶意应用
会对用户构成超出原生应用 OAuth 使用范围的一般且持续风险。
许多操作系统通过要求明确的用户操作来更改
http 和 https 方案 URI 的默认处理程序,
来缓解此问题。¶
基于浏览器的应用是在 Web 浏览器中运行的客户端, 通常以 JavaScript 编写,也称为“单页应用”。这些类型的应用 具有与原生应用类似的特定安全考虑。¶
TODO:在 browser-based apps BCP 最终确定后,引入其规范性文本。¶
本草案整合了 OAuth 2.0 [RFC6749]、 OAuth 2.0 for Native Apps [RFC8252]、 Proof Key for Code Exchange [RFC7636]、 OAuth 2.0 for Browser-Based Apps [I-D.ietf-oauth-browser-based-apps]、 OAuth Security Best Current Practice [RFC9700] 以及 Bearer Token Usage [RFC6750] 中的功能。¶
如果后续草案更新或废止了原始 [RFC6749] 中的功能, 则本草案中的相应功能会按照后续草案中描述的规范性 变更进行更新,或被完全移除。¶
下面列出从 OAuth 2.0 发生变化的非规范性列表:¶
授权码授予扩展了来自 PKCE [RFC7636] 的功能,使得按照本规范使用授权码授予的默认方法 要求添加 PKCE 参数¶
Implicit grant(response_type=token)按照
第
2.1.2 节,出自 [RFC9700]
从本规范中省略¶
Resource Owner Password Credentials grant 按照 第 2.4 节,出自 [RFC9700] 从本规范中省略¶
公开客户端的刷新令牌必须是发送方约束的或 一次性使用的,按照 第 4.14.2 节,出自 [RFC9700]¶
包含授权码的令牌端点请求不再包含
redirect_uri 参数¶
授权服务器必须支持请求正文中的客户端凭据¶
OAuth 2.0 Implicit grant 从 OAuth 2.1 中省略, 因为它已在 [RFC9700] 中弃用。¶
移除 Implicit grant 的意图是不再在授权响应中颁发访问令牌,
因为此类令牌容易泄露和注入,并且无法对客户端进行发送方约束。
此行为过去由客户端使用 response_type=token 参数表示。
OAuth 2.1 不再定义 response_type 参数的此值。¶
移除 response_type=token 不会影响从授权端点返回其他工件的
其他扩展响应类型,
例如由 [OpenID.Connect] 定义的
response_type=id_token。¶
在 OAuth 2.0 中,授权码流程中的令牌端点请求
(第
4.1.3 节,出自 [RFC6749])
包含一个可选的 redirect_uri 参数。该参数意在防止
授权码注入攻击,并且如果原始授权请求中发送了
redirect_uri 参数,则它是必需的。只有当特定客户端
注册了多个重定向 URI 时,授权请求才要求
redirect_uri 参数。然而在实践中,许多授权服务器实现
即使只注册了一个重定向 URI,也要求授权请求包含
redirect_uri 参数,导致令牌端点也要求该
redirect_uri 参数。¶
在 OAuth 2.1 中,授权码注入通过
code_challenge 和 code_verifier 参数防止,
因而在令牌请求中包含 redirect_uri 参数没有任何作用。
因此,它已被移除。¶
对于希望同时支持 OAuth 2.0 和 OAuth 2.1 客户端的
授权服务器的向后兼容性,授权服务器必须允许客户端在
令牌请求(第 4.1.3 节)中发送
redirect_uri 参数,并且必须按
[RFC6749] 中所述强制执行该参数。
授权服务器可以使用请求中的 client_id
来确定是否针对它知道将使用旧 OAuth 2.0 行为的特定客户端
强制执行此行为。¶
仅遵循 OAuth 2.1 建议的客户端不会在
令牌请求中发送 redirect_uri,因此将无法与
期望令牌请求中存在该参数的授权服务器兼容。¶
本节为本规范中定义的元素提供增强巴科斯-瑙尔范式 (ABNF) 语法描述,使用 [RFC5234] 的记法。下面的 ABNF 是以 Unicode 代码点 [W3C.REC-xml-20081126] 定义的;这些字符通常 以 UTF-8 编码。元素按照首次定义的顺序呈现。¶
下面的一些定义使用来自 [RFC3986] 的 "URI-reference" 定义。¶
下面的一些定义使用这些公共定义:¶
VSCHAR = %x20-7E NQCHAR = %x21 / %x23-5B / %x5D-7E NQSCHAR = %x20-21 / %x23-5B / %x5D-7E¶
client-id = *VSCHAR¶
client_secret 元素定义于 第 2.4.1 节:¶
client-secret = *VSCHAR¶
response_type 元素定义于 第 4.1.1 节 和 第 6.4 节:¶
response-type = response-name *( SP response-name ) response-name = 1*response-char response-char = "_" / DIGIT / ALPHA¶
scope = scope-token *( SP scope-token ) scope-token = 1*NQCHAR¶
state 元素定义于 第 4.1.1 节、第 4.1.2 节 和 第 4.1.2.1 节:¶
state = 1*VSCHAR¶
error 元素定义于 第 4.1.2.1 节、第 3.2.4 节
和 第 5.3 节:¶
error = 1*NQSCHAR¶
error_description 元素定义于 第 4.1.2.1 节、
第 3.2.4 节 和 第 5.3 节:¶
error-description = 1*NQSCHAR¶
error_uri 元素定义于 第 4.1.2.1 节、第 3.2.4 节
和 第 5.3 节:¶
error-uri = URI-reference¶
grant-type = grant-name / URI-reference grant-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA¶
access_token 元素定义于 第 3.2.3 节:¶
access-token = 1*VSCHAR¶
token_type 元素定义于 第 3.2.3 节 和 第 6.1 节:¶
token-type = type-name / URI-reference type-name = 1*name-char name-char = "-" / "." / "_" / DIGIT / ALPHA¶
expires-in = 1*DIGIT¶
code_verifier 的 ABNF 如下。¶
code-verifier = 43*128unreserved unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" ALPHA = %x41-5A / %x61-7A DIGIT = %x30-39¶
code_challenge 的 ABNF 如下。¶
code-challenge = 43*128unreserved unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" ALPHA = %x41-5A / %x61-7A DIGIT = %x30-39¶
在 [RFC6749] 发布时,
application/x-www-form-urlencoded 媒体类型定义在
[W3C.REC-html401-19991224] 的第
17.13.4 节中,
但未在 IANA MIME Media Types 注册表
(http://www.iana.org/assignments/media-types)
中注册。此外,该定义并不完整,因为它没有考虑非 US-ASCII
字符。¶
为了解决使用此媒体类型生成内容时的这一不足, 名称和值必须首先使用 UTF-8 字符编码方案 [RFC3629] 进行编码; 然后所得八位字节序列需要进一步使用 [W3C.REC-html401-19991224] 中定义的转义规则进行编码。¶
当解析使用此媒体类型的内容中的数据时, 反转名称/值编码后得到的名称和值也因此需要被视为 八位字节序列,并使用 UTF-8 字符编码方案解码。¶
例如,由六个 Unicode 代码点组成的值: (1) U+0020 (SPACE)、(2) U+0025 (PERCENT SIGN)、 (3) U+0026 (AMPERSAND)、(4) U+002B (PLUS SIGN)、 (5) U+00A3 (POUND SIGN) 和 (6) U+20AC (EURO SIGN),会被编码为 以下八位字节序列(使用十六进制表示):¶
20 25 26 2B C2 A3 E2 82 AC¶
然后在内容中表示为:¶
+%25%26%2B%C2%A3%E2%82%AC¶
本规范中的各种消息使用下面描述的方法之一进行序列化。 本节描述这些序列化方法的语法;其他章节描述它们何时可以以及必须使用。 注意,并非所有方法都可用于所有消息。¶
为了使用查询字符串序列化来序列化参数, Client 通过使用由 [WHATWG.URL] 定义的 application/x-www-form-urlencoded 格式,将参数和值添加到 URL 的查询组件中来 构造该字符串。查询字符串序列化通常用于 HTTP GET 请求。¶
以下是在发布时已确立的一些扩展列表:¶
Token Revocation 扩展定义了一种机制, 使客户端能够向授权服务器指示某个访问令牌不再需要。¶
Dynamic Client Registration 提供了一种机制, 用于以编程方式向授权服务器注册客户端。¶
Token Introspection 扩展定义了一种机制, 使资源服务器能够获取有关访问令牌的信息。¶
Authorization Server Metadata(也称为 OAuth Discovery) 定义了一个端点,客户端可以使用它来查找与特定 OAuth 服务器交互 所需的信息,例如授权端点和令牌端点的位置 以及受支持的授予类型。¶
Device Authorization Grant(以前称为 Device Flow)是一种扩展,使没有浏览器或输入能力有限的设备 能够获得访问令牌。这通常由智能电视应用, 或者可以将视频流式传输到流媒体视频服务的硬件视频编码器等设备使用。¶
Mutual TLS 描述了一种通过 TLS 证书认证 将令牌绑定到其被颁发给的客户端的机制, 以及一种客户端认证机制。¶
为客户端提供一种方式,向授权服务器明确表明 它打算在哪里使用其请求的访问令牌。¶
[RFC9068]:OAuth 2.0 访问令牌的 JSON Web Token (JWT) Profile¶
本规范定义了一种 Profile, 用于以 JSON Web Token (JWT) 格式颁发 OAuth 访问令牌。¶
Pushed Authorization Requests 扩展描述了一种 从后信道发起 OAuth 流程的技术,为构建复杂授权请求 提供更好的安全性和更大的灵活性。¶
授权响应中的 iss 参数
指示授权服务器的身份,以防止客户端中的混淆攻击。¶
Rich Authorization Requests 指定了一个新参数
authorization_details,用于在 OAuth 授权请求中携带细粒度授权数据。¶
DPoP 描述了一种机制,用于通过应用层上的 持有证明机制对 OAuth 2.0 令牌进行发送方约束。¶
Step-Up Auth 描述了一种机制, 资源服务器可用它向客户端表明当前请求访问令牌所关联的认证事件 不满足其认证要求。¶
本规范是 OAuth Working Group 的工作,其起点 基于以下规范的内容:OAuth 2.0 Authorization Framework (RFC 6749)、 OAuth 2.0 for Native Apps (RFC 8252)、OAuth Security Best Current Practice, 以及 OAuth 2.0 for Browser-Based Apps。编辑者感谢所有参与创建这些 本规范所基于的规范的人。¶
编辑者还要感谢以下人员,他们的想法、反馈、 修正以及措辞帮助塑造了本版本规范:Andrii Deinega、 Bob Hamburg、Brian Campbell、Daniel Fett、Deng Chao、Emelia Smith、Falko、Filip Skokan、Joseph Heenan、 Justin Richer、Karsten Meyer zu Selhausen、Michael Jones、Michael Peck、Roberto Polli、Tim Würtele 和 Vittorio Bertocci。¶
围绕本规范的讨论也曾在 2021 年和 2022 年的 OAuth Security Workshop 上进行。作者感谢该研讨会的组织者(Guido Schmitz、Steinar Noem 和 Daniel Fett)举办了有助于协作和社区输入的活动。¶
[[ 将从最终规范中移除 ]]¶
-15¶
为 JWT 客户端认证添加额外上下文,并特别 推荐 RFC7523bis¶
编辑性澄清和更新¶
澄清授权端点和令牌端点中的错误响应¶
同步 RFC9700 中关于 AS 开放重定向考虑的语言¶
应用 RFC6750 勘误 3500 和 6613¶
解决关于重复参数的歧义¶
-14¶
编辑性澄清¶
更正一处 "relying party" 与 "resource server" 的用法¶
添加来自 RFC7591 的 client_secret_post 和
client_secret_basic 术语引用¶
将 "sanitize" 表述替换为视为不受信任输入¶
澄清原生应用指南主要适用于移动应用平台¶
澄清没有要求 AS 特别支持公开客户端或 机密客户端¶
-13¶
-12¶
更新关于客户端注册的语言,以更好反映 替代注册方法,例如 OpenID Federation 和开放生态系统中使用的方法¶
将 DPoP 和 Step-Up Auth 添加到扩展附录中¶
将认证方案大小写不敏感的引用从 ABNF 更新为 HTTP¶
更正一处 "relying party" 与 "client" 的用法¶
将 client_id 要求移到各个授予类型中¶
将序列化方法的描述整合到附录中¶
-11¶
-10¶
澄清 client id 是不透明字符串¶
扩展可以在资源请求上定义额外错误代码¶
改进 error 字段定义的格式¶
将 "scope" 定义移动并扩展到引言章节¶
将访问令牌章节拆分为结构和请求¶
将 b64token 重命名为 token68,以与 RFC7235 保持一致¶
恢复旧附录 B 中关于 application/x-www-form-urlencoded 的内容¶
澄清客户端不得解析访问令牌¶
扩展关于何时在授权请求中要求
redirect_uri 参数的文本¶
为保持一致,在刷新令牌章节中将 "permissions" 改为 "privileges"¶
整合授权码流程安全考虑¶
澄清授权码重用——一个授权码只能 获得一次访问令牌¶
-09¶
AS 不得在授权端点支持 CORS 请求¶
关于非对称客户端认证的更多细节¶
从 security BCP 同步 CSRF 描述¶
更新并移动发送方约束访问令牌章节¶
与 security BCP 同步“客户端冒充资源所有者”¶
从重定向 URI 注册章节添加对授权请求的引用¶
从 security BCP 同步刷新轮换章节¶
从 security BCP 同步重定向 URI 匹配文本¶
更新对 RAR (RFC9396) 的引用¶
关于 URI 的澄清¶
从令牌请求中移除 redirect_uri¶
扩展围绕 code_verifier 的安全考虑¶
修订引言章节¶
-08¶
更新致谢¶
在 client ID 定义中将 "by a trusted party" 替换为 "by an outside party"¶
将 "verify the identity of the resource owner" 替换为 "authenticate"¶
澄清刷新令牌轮换,以匹配 RFC6819¶
添加附录以保存 application/x-www-form-urlencoded 示例¶
修正对附录中条目的引用¶
纳入来自 Security BCP 的新“通过 AS 钓鱼”章节¶
重述客户端认证动机的描述¶
将令牌请求中的 "scope" 参数移到特定授予类型中, 以匹配 OAuth 2.0¶
从最新版 Security BCP 更新点击劫持和开放重定向描述¶
将规范性要求移出授权码安全考虑章节¶
安全考虑澄清,并移除重复章节¶
-07¶
从摘要中移除 "third party"¶
在引言中添加 MFA 和 passwordless 作为额外动机¶
提到 PAR 是一种可以发生重定向 URI 注册的方式¶
添加对要求令牌端点使用 CORS 标头的引用¶
更新对 OMAP 扩展的引用¶
修正序列图中的编号¶
-06¶
移除 "credentialed client" 术语¶
简化 "confidential" 和 "public" 客户端的定义¶
纳入引用 RFC9207 的 iss 响应参数¶
添加关于 RS 进行访问令牌验证的章节¶
移除授权服务器必须支持原生应用全部 3 种重定向方法的要求¶
修复一些引用¶
将 HTTP 引用更新为 RFC 9110¶
澄清 "authorization grant" 术语¶
澄清客户端凭据授予用法¶
清理授权码图¶
更新 application/x-www-form-urlencoded 的引用,并移除 关于其未在 IANA 注册表中的过时说明¶
-05¶
添加关于移除 implicit flow 的章节¶
将许多规范性要求从安全考虑移动到 适当的内联章节中¶
重组并整合 TLS 语言¶
要求重定向 URI 使用 TLS,localhost/custom URL scheme 除外¶
更新刷新令牌指南以匹配 security BCP¶
-04¶
-03¶
重构,将所有授予类型收集到第 4 节的同一顶级标题下¶
更好地将规范性文本和安全考虑文本拆分到 适当位置,既将实际上属于安全考虑的文本从文档主体中移出, 也将安全考虑章节中的规范性要求拉入文档主体的适当部分¶
纳入 RFC6749 上许多已发布的勘误¶
更新对各个 RFC 的引用¶
整个文档中的编辑性澄清¶
-02¶
-01¶
-00¶
初始修订¶