RFC 9449 OAuth DPoP 2023 年 9 月
Fett, et al. 标准跟踪 [页]
流:
互联网工程任务组 (IETF)
RFC:
9449
类别:
标准跟踪
发布:
ISSN:
2070-1721
作者:
D. Fett
Authlete
B. Campbell
Ping Identity
J. Bradley
Yubico
T. Lodderstedt
Tuconic
M. Jones
Self-Issued Consulting
D. Waite
Ping Identity

RFC 9449

OAuth 2.0 持有证明演示(DPoP)

摘要

本文档描述了一种机制,用于通过应用层上的持有证明机制对 OAuth 2.0 令牌进行发送方约束。 该机制允许检测针对访问令牌和刷新令牌的重放攻击。

本备忘录状态

这是一份互联网标准跟踪文档。

本文档是互联网工程任务组 (IETF) 的产物。它代表了 IETF 社群的共识。它已经 接受公开审查,并已获 互联网工程指导组 (IESG) 批准发布。有关 互联网标准的更多信息可在 RFC 7841 第 2 节中找到。

有关本文档当前状态、任何 勘误以及如何提供反馈的信息,可在 https://www.rfc-editor.org/info/rfc9449 获取。

目录

1. 引言

Demonstrating Proof of Possession (DPoP) 是一种应用层机制,用于 对 OAuth [RFC6749] 访问令牌和 刷新令牌进行发送方约束。它使客户端能够通过在 HTTP 请求中包含 一个 DPoP 标头来证明其拥有公钥/私钥密钥对。该标头的值是一个 JSON Web Token (JWT) [RFC7519],它使授权 服务器能够将所签发的令牌绑定到客户端密钥对的公钥部分。 这些令牌的接收者随后能够验证令牌与该密钥对之间的绑定,而客户端已通过 DPoP 标头证明其持有该密钥对,从而提供一定保证:出示 该令牌的客户端也拥有私钥。 换言之,令牌的合法出示者被约束为持有并证明拥有该 密钥对私钥部分的发送方。

此处规定的机制可用于其他 利用底层安全传输层元素来对令牌进行发送方约束的方法(例如 [RFC8705][TOKEN-BINDING]) 不可用或不可取的情况。例如,由于用户代理中的 TLS 客户端认证体验欠佳, 且缺乏对 HTTP 令牌绑定的支持,如果 OAuth 客户端是一个动态下载并在 Web 浏览器中执行的应用(有时称为 “单页应用”),则这两种机制都无法使用。 此外,直接安装并运行在用户设备上的应用 很适合从 DPoP 绑定令牌中受益,因为这种令牌可防止 被攻陷或恶意资源滥用令牌。 这类应用通常具有专用的受保护存储空间 用于加密密钥。

无论采用何种客户端认证方法,DPoP 都可用于对访问令牌进行发送方约束, 但 DPoP 本身并不用于客户端认证。 DPoP 还可用于对签发给公共客户端的刷新令牌进行发送方约束 (公共客户端指没有与 client_id 关联的认证凭据的客户端)。

1.1. 约定与 术语

本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“NOT RECOMMENDED”、 “MAY” 和 “OPTIONAL” 应按 BCP 14 [RFC2119] [RFC8174] 中的说明解释, 且仅当它们像这里所示以全大写形式出现时才如此解释。

本规范使用 [RFC5234] 中的扩展巴科斯-诺尔范式 (ABNF) 表示法。

本规范使用 “The OAuth 2.0 Authorization Framework” [RFC6749] 中定义的术语 “access token”、“refresh token”、 “authorization server”、“resource server”、“authorization endpoint”、 “authorization request”、“authorization response”、“token endpoint”、 “grant type”、“access token request”、“access token response”、 “client”、“public client” 和 “confidential client”。

术语 “request”、“response”、“header field” 和 “target URI” 引自 [RFC9110]

术语 “JOSE” 和 “JOSE Header” 引自 [RFC7515]

本文档包含部分和完整 HTTP 消息的非规范性示例。 一些示例使用单个尾随反斜杠来表示长值的换行,如 [RFC8792] 所述。 该字符以及换行行上的前导空格不是值的一部分。

2. 目标

DPoP 的主要目标是通过在签发时将令牌绑定到公钥, 并要求客户端在使用令牌时证明其拥有相应私钥, 从而防止未授权或非法方使用泄露或被盗的访问令牌。 这会将令牌的合法发送方约束为仅拥有私钥访问权的一方, 并为接收该令牌的服务器提供额外保证,表明发送方被合法授权使用该令牌。

因此,通过 DPoP 进行发送方约束的访问令牌与 典型的 bearer token 形成对比,后者可被任何持有该令牌的一方使用。 虽然通常存在保护措施以防止 bearer token 被意外披露, 但由于协议或软件栈其他层中的漏洞和实现问题,仍发生过不可预见的泄露途径 (例如 Compression Ratio Info-leak Made Easy (CRIME) [CRIME]、Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext (BREACH) [BREACH]、 Heartbleed [Heartbleed] 以及 Cloudflare 解析器 bug [Cloudbleed])。 也有许多已公开的针对 OAuth 实现自身的令牌窃取攻击([GitHub.Tokens] 只是一个高知名度示例)。 DPoP 针对意外令牌泄露的影响提供了一种通用的纵深防御。 然而,DPoP 不能替代安全传输,并且 MUST 始终与 HTTPS 结合使用。

典型 OAuth 协议交互的本质 要求客户端将访问令牌披露给其访问的 受保护资源。[SECURITY-TOPICS] 中的攻击者模型描述了一些情况,其中 受保护资源可能是伪造的、恶意的或被攻陷的, 并会将收到的令牌拿到其他受保护资源处重放以获得 未授权访问。受众受限的访问令牌 (例如使用 JWT [RFC7519] aud 声明)可以 防止这种滥用。然而,实践中这样做对许多部署来说已被证明 过于繁琐(尽管存在诸如 [RFC8707] 之类的扩展)。 对访问令牌进行发送方约束是一种更稳健且更直接的机制, 可防止这类令牌在不同端点处被重放,而 DPoP 是实现这一点的一种易于采用的应用层手段。

由于存在跨站脚本 (XSS) 的可能性,基于浏览器的 OAuth 客户端在令牌保护方面带来了额外考虑。 最直接的基于 XSS 的攻击是攻击者窃取令牌, 并完全独立于合法客户端自行使用该令牌。 被盗的访问令牌可用于访问受保护资源, 被盗的刷新令牌可用于获取新的访问令牌。 如果私钥不可导出(如 [W3C.WebCryptoAPI] 所支持的那样), DPoP 会使单独被窃取的令牌无法使用。

XSS 漏洞还允许攻击者在基于浏览器的客户端应用上下文中执行代码, 并通过该客户端间接恶意使用令牌。 该执行上下文可以访问并使用签名密钥; 因此,它可以生成 DPoP 证明并与令牌一起使用。 在此应用层,除了通常防止 XSS 之外,最可能不存在针对该威胁的可行防御; 因此,这被视为 DPoP 的范围之外。

在基于浏览器的客户端应用上下文中执行的恶意 XSS 代码 还能够创建带有未来时间戳值的 DPoP 证明, 并将它们与令牌一起窃取。这些被盗 构件随后可独立于客户端应用使用,以 访问受保护资源。为防止这种情况,服务器可以选择要求 客户端在证明中包含一个由服务器选择且攻击者无法预测的值 (nonce)。在没有可选 nonce 的情况下,预先计算的 DPoP 证明的影响 在某种程度上受到限制,因为在访问受保护资源时证明会绑定到 访问令牌。由于覆盖尚不存在访问令牌的证明无法实际创建, 因此使用被窃取的刷新令牌和预先计算证明所获得的访问令牌将无法使用。

其他安全注意事项在 第 11 节 中讨论。

3. 概念

本规范引入的主要数据结构是 DPoP 证明 JWT,它作为 HTTP 请求中的标头发送, 如下文详细描述。客户端使用 DPoP 证明 JWT 来证明 其拥有与某个公钥相对应的私钥。

大致而言,DPoP 证明是对以下内容的签名:

+--------+                                          +---------------+
|        |--(A)-- Token Request ------------------->|               |
| Client |        (DPoP Proof)                      | Authorization |
|        |                                          |     Server    |
|        |<-(B)-- DPoP-Bound Access Token ----------|               |
|        |        (token_type=DPoP)                 +---------------+
|        |
|        |
|        |                                          +---------------+
|        |--(C)-- DPoP-Bound Access Token --------->|               |
|        |        (DPoP Proof)                      |    Resource   |
|        |                                          |     Server    |
|        |<-(D)-- Protected Resource ---------------|               |
|        |                                          +---------------+
+--------+
图 1基本 DPoP 流程

带有 DPoP 的 OAuth 流程(不含可选 nonce)的基本步骤如 图 1 所示。

  1. 在令牌请求中,客户端向授权服务器发送授权授予 (例如授权码、刷新令牌等),以获得访问令牌 (以及可能的刷新令牌)。客户端在 HTTP 标头中将 DPoP 证明附加到该请求。
  2. 授权服务器将访问令牌绑定(发送方约束)到客户端在 DPoP 证明中声明的 公钥;也就是说,如果不证明拥有相应私钥,访问令牌就不能使用。 如果向公共客户端签发刷新令牌,它也会绑定到 DPoP 证明的公钥。
  3. 为了使用访问令牌,客户端必须再次通过向请求添加一个承载 该请求 DPoP 证明的标头,来证明 其拥有私钥。资源服务器需要接收有关访问令牌所绑定公钥的信息。 该信息可以直接编码到访问令牌中(对于 JWT 结构的访问令牌),也可以通过令牌 内省端点提供(未显示)。 资源服务器验证访问令牌所绑定的公钥 是否与 DPoP 证明中的公钥匹配。 它还会验证 DPoP 证明中的访问令牌哈希是否与请求中出示的 访问令牌匹配。
  4. 如果签名检查失败,或者 DPoP 证明中的数据错误, 例如目标 URI 与 DPoP 证明 JWT 中的 URI 声明不匹配, 资源服务器会拒绝服务该请求。当然,访问令牌本身 在所有其他方面也必须有效。

此处介绍的 DPoP 机制不是客户端认证方法。 事实上,DPoP 的一个主要用例是面向不使用客户端认证的公共客户端 (例如单页应用和用户设备上的应用)。尽管如此, DPoP 被设计为与 private_key_jwt 以及所有 其他客户端认证方法兼容。

DPoP 并不直接确保消息完整性,而是依赖 TLS 层实现该目的。详见 第 11 节

4. DPoP 证明 JWT

DPoP 引入了 DPoP 证明这一概念,它是由 客户端创建并使用 DPoP 标头字段随 HTTP 请求发送的 JWT。 每个 HTTP 请求都需要一个唯一的 DPoP 证明。

有效的 DPoP 证明向服务器表明客户端持有用于签署该 DPoP 证明 JWT 的私钥。这使授权服务器能够将 所签发的令牌绑定到相应的公钥(如 第 5 节 所述), 也使资源服务器能够验证它所接收令牌的密钥绑定 (见 第 7.1 节),从而防止 这些令牌被任何无法访问该私钥的实体使用。

DPoP 证明用于证明拥有某个密钥,其本身并不是 认证或访问控制机制。当它与如 第 7.1 节 所述的密钥绑定访问令牌一起出示时, DPoP 证明可为客户端出示该访问令牌的合法性 提供额外保证。然而,一个有效的 DPoP 证明 JWT 本身 并不足以作出访问控制决策。

4.1. DPoP HTTP 标头

DPoP 证明使用以下请求标头 字段包含在 HTTP 请求中。

DPoP:
遵循 第 4.2 节 的结构和 语法的 JWT。

图 2 展示了一个 DPoP HTTP 标头字段示例。该示例根据 [RFC8792] 使用 “\” 换行。

DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg
图 2DPoP 标头示例

注意,根据 [RFC9110], 标头字段名不区分大小写;因此,DPoPDPOPdpop 等都是有效且等价的标头 字段名。然而,标头字段值中的大小写是有意义的。

DPoP HTTP 标头字段值 使用 第 11.2 节 of [RFC9110] 中定义的 token68 语法, 并为便于参考在下方 图 3 中重复列出。

DPoP       = token68
token68    = 1*( ALPHA / DIGIT /
                 "-" / "." / "_" / "~" / "+" / "/" ) *"="
图 3DPoP 标头字段 ABNF

4.2. DPoP 证明 JWT 语法

DPoP 证明是一个 JWT [RFC7519],它使用客户端选择的私钥(见下文) 通过 JSON Web Signature (JWS) [RFC7515] 签名。 DPoP JWT 的 JOSE Header MUST 至少包含以下 参数:

typ:
值为 dpop+jwt 的字段,它按照 第 3.11 节 of [RFC8725] 的建议, 显式地将 DPoP 证明 JWT 类型化。
alg:
来自 [IANA.JOSE.ALGS] 的 JWS 非对称数字 签名算法标识符。它 MUST NOTnone 或对称 算法(消息认证码 (MAC))的标识符。
jwk:
表示客户端选择的公钥, 其格式为 JSON Web Key (JWK) [RFC7517], 如 第 4.1.3 节 of [RFC7515] 中所定义。它 MUST NOT 包含私钥。

DPoP 证明的载荷 MUST 至少包含 以下声明:

jti:
DPoP 证明 JWT 的唯一标识符。 该值 MUST 以这样的方式分配:在有效时间窗口内的相同上下文中, 将同一个值分配给任何 其他 DPoP 证明的概率可以忽略不计。 这种唯一性可以通过编码(base64url 或任何其他 合适的编码)至少 96 位 伪随机数据来实现,或者通过使用符合 [RFC4122] 的第 4 版通用唯一标识符 (UUID) 字符串来实现。 服务器可以使用 jti 进行重放 检测和防止;见 第 11.1 节
htm:
JWT 所附加请求的 HTTP 方法(第 9.1 节 of [RFC9110])的值。
htu:
JWT 所附加请求的 HTTP target URI(第 7.1 节 of [RFC9110]),不含查询和片段 部分。
iat:
JWT 的创建时间戳(第 4.1.6 节 of [RFC7519])。

当 DPoP 证明与受保护资源访问中出示访问 令牌结合使用时(见 第 7 节),DPoP 证明 MUST 还包含以下声明:

ath:
访问令牌的哈希。 该值 MUST 是关联访问令牌值的 ASCII 编码的 SHA-256 [SHS] 哈希经过 base64url 编码(如 第 2 节 of [RFC7515] 中定义)后的结果。

当认证服务器或资源服务器在响应中提供 DPoP-Nonce HTTP 标头时 (见第 8 节和第 9 节),DPoP 证明 MUST 还包含 以下声明:

nonce:
通过 DPoP-Nonce HTTP 标头提供的近期 nonce。

DPoP 证明 MAY 包含由扩展、 配置文件或特定部署要求定义的其他 JOSE Header Parameters 或声明。

图 4 是一个概念性 示例,展示了 图 2 中 DPoP 证明的解码内容。JWT 标头和载荷的 JSON 被显示出来, 但签名部分被省略。照例,换行和额外空格 用于格式化和可读性。

{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"-BwC3ESc6acc2lTc",
  "htm":"POST",
  "htu":"https://server.example.com/token",
  "iat":1562262616
}
图 4 DPoP 证明的 JWT 内容示例

在 HTTP 请求中,只有 HTTP 方法和 URI 被包含在 DPoP JWT 中;因此,只有这两个消息部分 被 DPoP 证明覆盖。 其思路是只对足够的 HTTP 数据进行签名, 以针对该 HTTP 请求提供合理的持有证明。 这种只使用 HTTP 标头数据最小子集的设计方法, 是为了避免试图规范化 HTTP 消息时固有的重大困难。 尽管如此,DPoP 证明可以扩展为包含 HTTP 请求中的其他信息 (另见 第 11.7 节)。

4.3. 检查 DPoP 证明

为验证 DPoP 证明,接收服务器 MUST 确保以下各项:

  1. 不存在多于一个 DPoP HTTP 请求标头 字段。
  2. DPoP HTTP 请求标头字段值是单个且格式良好的 JWT。
  3. JWT 中包含 第 4.2 节 所要求的全部声明。
  4. typ JOSE Header Parameter 的值为 dpop+jwt
  5. alg JOSE Header Parameter 表示一个已注册的 非对称数字 签名算法 [IANA.JOSE.ALGS],不是 none, 受应用支持,并且根据本地策略可接受。
  6. JWT 签名可用 jwk JOSE Header Parameter 中包含的公钥验证通过。
  7. jwk JOSE Header Parameter 不包含私 钥。
  8. htm 声明与当前 请求的 HTTP 方法匹配。
  9. htu 声明与接收该 JWT 的 HTTP 请求的 HTTP URI 值匹配,忽略任何查询和 片段部分。
  10. 如果服务器向客户端提供了 nonce 值, nonce 声明与服务器提供的 nonce 值匹配。
  11. JWT 的创建时间(由 iat 声明或通过 nonce 声明由服务器管理的时间戳确定) 位于可接受的窗口内(见 第 11.1 节)。
  12. 如果它与访问令牌一起出示给受保护资源,

    • 确保 ath 声明的值等于该访问令牌的哈希,并且
    • 确认访问令牌所绑定的公钥 与 DPoP 证明中的公钥匹配。

为减少误报阴性的可能性, 服务器 SHOULD 在比较 htu 声明之前, 采用基于语法的规范化(第 6.2.2 节 of [RFC3986])和基于方案的 规范化(第 6.2.3 节 of [RFC3986])。

这些检查可以按任意顺序执行。

5. DPoP 访问令牌请求

为了使用 DPoP 请求绑定到公钥的访问令牌,客户端在向授权服务器的令牌端点发起 访问令牌请求时,MUSTDPoP 标头中提供一个有效的 DPoP 证明 JWT。这适用于所有 访问令牌请求,不论授予类型如何(例如, 常见的 authorization_coderefresh_token 授予类型,以及诸如 JWT 授权授予 [RFC7523] 之类的扩展 授予)。 图 5 中显示的 HTTP 请求说明了这样一个访问 令牌请求:使用授权码授予,并在 DPoP 标头中携带 DPoP 证明 JWT。图 5 根据 [RFC8792] 使用 “\” 换行。

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

grant_type=authorization_code\
&client_id=s6BhdRkqt\
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
&code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-
图 5使用授权码请求 DPoP 发送方约束令牌的令牌请求

DPoP HTTP 标头字段 MUST 包含一个有效的 DPoP 证明 JWT。 如果 DPoP 证明无效,授权服务器会按照 第 5.2 节 of [RFC6749] 发出错误 响应,并将 invalid_dpop_proof 作为 error 参数的值。

在检查 DPoP 证明的有效性之后,为了对访问令牌进行发送方约束, 授权服务器会将所签发的访问令牌与 DPoP 证明中的 公钥关联起来,这可以按 第 6 节 中所述的方式完成。 访问令牌响应中 MUST 包含 DPoPtoken_type, 以向客户端表明该访问令牌已绑定到 其 DPoP 密钥,并且可按 第 7.1 节 中所述使用。 图 6 中显示的示例响应说明了这样一个 响应。

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
 "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU",
 "token_type": "DPoP",
 "expires_in": 2677,
 "refresh_token": "Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g"
}
图 6访问令牌响应

图 6 中的示例响应包含一个刷新令牌, 客户端可在先前的访问令牌过期时使用它来获取新的访问令牌。 刷新访问令牌是使用 refresh_token 授予类型向授权服务器的令牌端点发起的令牌请求。与 所有访问令牌请求一样,客户端通过包含 DPoP 证明,将其作为 DPoP 请求,如 图 7 所示。图 7 根据 [RFC8792] 使用 “\” 换行。

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjY1Mjk2fQ.pAqut2IRDm_De6PR93SYmGBPXpwrAk90e8cP2hjiaG5Qs\
 GSuKDYW7_X620BxqhvYC8ynrrvZLTk41mSRroapUA

grant_type=refresh_token\
&client_id=s6BhdRkqt\
&refresh_token=Q..Zkm29lexi8VnWg2zPW1x-tgGad0Ibc3s3EwM_Ni4-g
图 7使用刷新令牌请求 DPoP 绑定令牌的 令牌请求

当支持 DPoP 的授权服务器向在令牌端点出示有效 DPoP 证明的 公共客户端签发刷新令牌时,该刷新令牌 MUST 绑定 到相应的公钥。稍后出示该刷新令牌以获取新的访问令牌时, 该绑定 MUST 被验证。因此,此类客户端 每次使用该刷新令牌获取新的访问令牌时, MUST 为获取该刷新令牌时所用的同一密钥出示 DPoP 证明。 刷新令牌绑定的实现细节由 授权服务器自行决定。由于授权服务器既生成又 验证其刷新令牌,因此该绑定的具体细节不存在互操作性 考量。

授权服务器 MAY 选择签发未绑定 DPoP 的访问令牌, 这会按照 [RFC6750],通过访问令牌响应的 token_type 参数中 Bearer 的值向客户端发出信号。对于同时被签发刷新令牌的 公共客户端,这会产生仅对刷新令牌进行 DPoP 绑定的效果, 即使受保护资源尚未更新为支持 DPoP,也能改善安全态势。

如果访问令牌响应包含与 DPoP 不同的 token_type 值, 则不会提供 DPoP 所带来的 访问令牌保护。如果这种保护被认为对 应用的安全很重要,客户端在这种情况下 MUST 丢弃该响应;否则,客户端可以像常规 OAuth 交互一样继续。

签发给机密客户端(即已与授权服务器建立 认证凭据的客户端)的刷新令牌 不会绑定到 DPoP 证明公钥,因为它们已经 通过另一种现有机制进行了发送方约束。OAuth 2.0 Authorization Framework [RFC6749] 已经要求 授权服务器将刷新令牌绑定到其签发给的客户端, 并要求机密客户端在出示刷新令牌时 向授权服务器进行认证。因此,这类刷新令牌 通过客户端标识符和相关 认证要求实现发送方约束。与直接绑定到特定公钥相比, 这种现有的发送方约束机制 更加灵活(例如,它允许客户端轮换凭据 而不会使刷新令牌失效)。

5.1. 授权服务器 元数据

本文档引入以下授权服务器元数据 [RFC8414] 参数,用于表示总体上支持 DPoP,以及授权服务器支持用于 DPoP 证明 JWT 的具体 JWS alg 值。

dpop_signing_alg_values_supported:
一个 JSON 数组,包含授权服务器支持用于 DPoP 证明 JWT 的 JWS alg 值(来自 [IANA.JOSE.ALGS] 注册表)列表。

5.2. 客户端注册 元数据

Dynamic Client Registration Protocol [RFC7591] 定义了一个 API, 用于向授权服务器动态注册 OAuth 2.0 客户端元数据。 [RFC7591] 定义的元数据及其 已注册扩展,也意味着一个适用于客户端的通用数据模型, 对授权服务器实现 很有用,即使未使用 Dynamic Client Registration Protocol 也是如此。 此类实现通常会提供某种用户界面,用于管理 客户端配置。

本文档引入以下客户端注册元数据 [RFC7591] 参数,用于表示 客户端在向授权服务器请求令牌时始终使用 DPoP。

dpop_bound_access_tokens:
一个布尔值,指定 客户端是否始终对令牌请求使用 DPoP。如果省略,则默认值为 false

如果该值为 true,授权服务器 MUST 拒绝来自该客户端且不包含 DPoP 标头的令牌请求。

6. 公钥确认

资源服务器 MUST 能够可靠地识别 访问令牌是否为 DPoP 绑定,并确定足够的信息, 以验证其与 DPoP 证明公钥的绑定(见 第 7.1 节)。 这种绑定是通过以受保护资源可以访问的方式 将公钥与令牌关联来完成的,例如 直接在签发的访问令牌中嵌入 JWK 哈希, 使用 第 6.1 节 中描述的语法, 或通过 第 6.2 节 中描述的令牌内省来完成。 根据授权服务器和受保护资源之间的约定,也可以使用其他方法 将公钥与访问令牌关联;然而,这些方法超出了 本规范的范围。

支持 DPoP 的资源服务器 MUST 确保 DPoP 证明中的公钥 与绑定到访问令牌的公钥匹配。

6.1. JWK 指纹 确认方法

当访问令牌表示为 JWT [RFC7519] 时, 公钥信息使用本文定义的 jkt 确认方法成员来表示。 为了在 JWT 中传达公钥的哈希,本规范引入以下 JWT Confirmation Method [RFC7800] 成员, 用于 cnf 声明之下。

jkt:
JWK SHA-256 指纹确认方法。 jkt 成员的值 MUST 是 DPoP 公钥(JWK 格式)的 JWK SHA-256 指纹(根据 [RFC7638])经过 base64url 编码(如 [RFC7515] 中定义)后的结果, 其中该访问令牌绑定到该 DPoP 公钥。

图 8 中的以下 JWT 示例,其解码后的 JWT 载荷显示在 图 9 中,包含一个带有 jkt JWK 指纹确认 方法成员的 cnf 声明。这些示例中的 jkt 值是 第 5 节 中示例 DPoP 证明里的公钥哈希。 该示例根据 [RFC8792] 使用 “\” 换行。

eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1\
wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE\
1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll\
5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO\
YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA
图 8包含 JWK SHA-256 指纹确认的 JWT
{
  "sub":"someone@example.com",
  "iss":"https://server.example.com",
  "nbf":1562262611,
  "exp":1562266216,
  "cnf":
  {
    "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  }
}
图 9带有 JWK SHA-256 指纹确认的 JWT 声明集

6.2. 令牌内省中的 JWK 指纹 确认方法

“OAuth 2.0 Token Introspection” [RFC7662] 定义了一种方法,使 受保护资源可以向授权服务器查询访问令牌的活动 状态。受保护资源还会确定关于该令牌的元信息。

对于 DPoP 绑定的访问令牌,该令牌所绑定公钥的哈希 会作为令牌内省响应中的元信息传达给受保护资源。 该哈希使用与 第 6.1 节 中所述 JWK 指纹确认方法相同的 cnf 内容和 jkt 成员结构,作为内省响应 JSON 的顶层成员传达。 注意,资源服务器不会随内省请求发送 DPoP 证明, 授权服务器也不会在内省端点验证访问令牌的 DPoP 绑定。 相反,资源服务器使用内省响应中的数据, 在本地自行验证访问令牌绑定。

如果内省响应中包含 token_type 成员, 它 MUST 包含 值 DPoP

图 10 中的示例内省请求及 图 11 中的相应响应, 说明了针对 图 6 中签发的示例 DPoP 绑定 访问令牌的内省交换。

POST /as/introspect.oauth2 HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic cnM6cnM6TWt1LTZnX2xDektJZHo0ZnNON2tZY3lhK1Rp

token=Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
图 10示例内省 请求
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "active": true,
  "sub": "someone@example.com",
  "iss": "https://server.example.com",
  "nbf": 1562262611,
  "exp": 1562266216,
  "cnf":
  {
    "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
  }
}
图 11DPoP 绑定访问令牌的示例内省 响应

7. 受保护资源访问

对 DPoP 保护资源的请求 MUST 同时包含按照 第 4 节 的 DPoP 证明,以及 第 7.1 节 中描述的访问令牌。 DPoP 证明 MUST 包含 ath 声明,该声明带有关联访问令牌的有效哈希。

以这种方式将令牌值绑定到证明,可防止一个证明 在不同请求中与多个不同的访问令牌值一起使用。 例如,如果客户端持有绑定到两个不同资源所有者 AT1 和 AT2 的令牌, 并在与授权服务器通信时使用同一个密钥,那么这些令牌可能会被 交换。 如果没有 ath 字段来绑定它,应用于 AT1 的捕获签名可能会 与 AT2 一起重放,从而改变预期请求的权利和访问权限。 对于同一客户端和资源所有者组合内轮换的访问令牌,这种替换防护同样保留—— 轮换后的令牌值将需要计算新的证明。 这种绑定还确保了打算与访问令牌一起使用的证明 不能在没有访问令牌的情况下使用,反之亦然。

资源服务器需要计算所出示令牌值的哈希, 并验证该哈希与 第 4.3 节 所述 ath 字段中的哈希值相同。 由于 ath 字段值由 DPoP 证明的签名覆盖, 包含它就会将访问令牌值绑定到用于生成该签名的密钥持有者。

注意,单独的 ath 字段并不能防止 DPoP 证明重放,也不能提供 与出示该证明的请求之间的绑定, 因此仍然需要检查证明的时间 窗口以及包含的消息参数,例如 htmhtu

7.1. DPoP 认证方案

DPoP 绑定的访问令牌使用 Authorization 请求 标头字段发送,按照 第 11.6.2 节 of [RFC9110],其认证方案为 DPoPDPoP 方案的 Authorization 标头字段语法 使用 第 11.2 节 of [RFC9110] 中定义的 token68 语法作为凭据, 并为便于参考在下方重复列出。 DPoP 认证方案凭据的 ABNF 表示法语法如下:

token68    = 1*( ALPHA / DIGIT /
                 "-" / "." / "_" / "~" / "+" / "/" ) *"="

credentials = "DPoP" 1*SP token68
图 12DPoP 认证方案 ABNF

对于这样的访问令牌,资源服务器 MUST 检查 HTTP 请求的 DPoP 标头字段中 是否也收到了 DPoP 证明, 根据 第 4.3 节 中的规则检查 DPoP 证明, 并按照 第 6 节 检查 DPoP 证明的公钥是否与访问令牌所绑定的公钥匹配。

除非所有 检查均成功,否则资源服务器 MUST NOT 授予对 资源的访问。

图 13 展示了一个访问受保护 资源的示例请求,其中 Authorization 标头中包含 DPoP 绑定的访问令牌, DPoP 标头中包含 DPoP 证明。 该示例根据 [RFC8792] 使用 “\” 换行。 图 14 展示了该 DPoP 证明的解码内容。JWT 标头和载荷的 JSON 被显示出来, 但签名部分被省略。照例,换行和缩进 用于格式化和可读性。

GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj\
 oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z\
 WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF\
 c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E\
 OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
图 13DPoP 保护资源 请求
{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"e1j3V_bKic8-LAEB",
  "htm":"GET",
  "htu":"https://resource.example.org/protectedresource",
  "iat":1562262618,
  "ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo"
}
图 14图 13 中 DPoP 证明 JWT 的解码内容

在收到保护空间内需要 DPoP 认证的受保护资源请求时, 如果该请求未包含有效凭据,或未包含足以 访问的访问令牌,服务器可以使用质询响应 客户端,要求其提供 DPoP 认证信息。 这种质询使用 401 (Unauthorized) 响应 状态码([RFC9110], 第 15.5.2 节)和 WWW-Authenticate 标头字段 ([RFC9110], 第 11.6.1 节)发出。服务器 MAY 也可以在响应其他条件时包含 WWW-Authenticate 标头。

在这种质询中:

  • 方案名称为 DPoP
  • 认证参数 realm MAY 被包含,用于按 [RFC9110], 第 11.5 节 所述方式表示 保护范围。
  • scope 认证参数 MAY[RFC6750], 第 3 节 的定义包含。
  • error 参数([RFC6750], 第 3 节SHOULD 被包含, 用于在请求包含访问令牌但认证失败时 指明请求被拒绝的原因。 [RFC6750], 第 3.1 节 中描述的 error 参数值是合适的, 扩展定义的任何适当值也适用。use_dpop_nonce 值可按 第 9 节 中所述使用,用于表示 后续请求的 DPoP 证明中需要 nonce。此外,invalid_dpop_proof 用于表示 DPoP 证明本身根据 第 4.3 节 的标准被判定为无效。
  • error_description 参数([RFC6750], 第 3 节MAYerror 参数一起包含,用于向开发者提供人类可读的 解释,该解释并不打算展示给最终用户。
  • algs 参数 SHOULD 被包含,用于向客户端表示 DPoP 证明 JWT 可接受的 JWS 算法。 该参数的值是由空格分隔的 JWS alg(Algorithm) 标头值列表([RFC7515], 第 4.1.1 节)。
  • 可以使用其他认证参数 MAY,且接收者 MUST 忽略未知参数。

图 15 展示了对一个没有 认证的受保护资源请求的响应。

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: DPoP algs="ES256 PS256"
图 15对没有认证的 受保护资源请求的 HTTP 401 响应

图 16 展示了对一个受保护资源请求的响应, 该请求因访问令牌中的 DPoP 绑定确认失败而被拒绝。图 16 根据 [RFC8792] 使用 “\” 换行。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="invalid_token", \
   error_description="Invalid DPoP key binding", algs="ES256"
图 16对带有无效令牌的 受保护资源请求的 HTTP 401 响应

注意,使用跨源资源共享 (CORS) [WHATWG.Fetch] 的 基于浏览器的客户端应用 默认只能访问 CORS 安全列出的响应 HTTP 标头。 为了让应用获取并使用 WWW-Authenticate HTTP 响应 标头值,服务器需要通过将 WWW-Authenticate 包含在 Access-Control-Expose-Headers 响应标头 列表值中,使其可供应用访问。

此认证方案仅用于源服务器认证。 因此,此认证方案 MUST NOTProxy-AuthenticateProxy-Authorization 标头字段一起使用。

注意,此认证方案的 Authorization 标头字段语法 遵循 第 2.1 节 of [RFC6750] 中定义的 Bearer 方案用法。 虽然它不是 [RFC9110] 的首选凭据语法, 但它与其中的通用认证框架兼容,并且用于与 Bearer 方案保持一致性 和熟悉性。

7.2. 与 Bearer 认证方案的兼容性

同时支持 DPoPBearer 方案的受保护资源,需要更新对 bearer token 的评估流程, 以防止 DPoP 绑定访问令牌的降级使用。 具体而言,这样的受保护资源 MUST 拒绝 按 [RFC6750] 作为 bearer token 接收的 DPoP 绑定 访问令牌。

第 11.6.1 节 of [RFC9110] 允许受保护资源使用 401 (Unauthorized) 响应中的 WWW-Authenticate 标头字段,表示支持 多种认证方案(即 BearerDPoP)。

只支持 [RFC6750] 且不了解 DPoP 的受保护资源 很可能会把 DPoP 绑定访问令牌作为 bearer token 接受 (JWT [RFC7519] 表示应忽略无法识别的 声明,Introspection [RFC7662] 表示可能存在其他参数,但并未对其存在施加功能性 要求,而 [RFC6750] 实际上对 访问令牌的内容保持沉默,因为它关注的是有效性)。 因此,客户端在收到来自受保护资源的 WWW-Authenticate: Bearer 质询时, 可以使用 Bearer 方案发送 DPoP 绑定访问令牌 (或者,如果它事先知道受保护资源的能力,也可以发送 DPoP 绑定访问令牌)。 这样做的效果可能会简化受保护资源分阶段升级以支持 DPoP 的 后勤工作,或简化具有混合令牌类型支持的受保护资源的 长期部署。

如果同时支持 BearerDPoP 方案的受保护资源选择 以多个 WWW-Authenticate 质询进行响应,则应注意 哪个或哪些质询应传递实际的错误信息。RECOMMENDED 遵循以下规则:

  • 如果请求中未包含任何认证信息,则 质询 SHOULD NOT 包含错误码或其他错误 信息,如 第 3.1 节 of [RFC6750] 所述(图 17)。

  • 如果可以明确确定用于尝试认证的机制, 则相应的质询 SHOULD 用于传递错误 信息(图 18)。

  • 否则,BearerDPoP 两种质询 MAY 都可用于传递错误信息(图 19)。

以下示例根据 [RFC8792] 使用 “\” 换行。

GET /protectedresource HTTP/1.1
Host: resource.example.org

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer, DPoP algs="ES256 PS256"
图 17对没有认证的 受保护资源请求的 HTTP 401 响应
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer INVALID_TOKEN

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", \
    error_description="Invalid token", DPoP algs="ES256 PS256"
图 18对带有无效认证的 受保护资源请求的 HTTP 401 响应
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU

HTTP/1.1 400 Bad Request
WWW-Authenticate: Bearer error="invalid_request", \
 error_description="Multiple methods used to include access token", \
 DPoP algs="ES256 PS256", error="invalid_request", \
 error_description="Multiple methods used to include access token"
图 19对带有模糊认证的 受保护资源请求的 HTTP 400 响应

7.3. 客户端注意事项

包含 DPoP 证明的授权可能不是幂等的(取决于服务器对 jtiiatnonce 声明的执行)。 因此,所有此前幂等的受保护资源请求 可能不再是幂等的。RECOMMENDED 客户端生成一个 唯一的 DPoP 证明,即使是在响应通常被理解为暂时性的 HTTP 错误而 重试幂等请求时也是如此。

当与采用更严格 nonce 验证 实现的服务器交互时,经常遇到网络错误的客户端可能会面临额外 挑战。

8. 授权服务器提供的 Nonce

本节规定了一种使用服务器提供的不透明 nonce 的机制, 可用于限制 DPoP 证明的生命周期。 如果不采用这种机制,控制客户端的恶意方 (可能包括最终用户) 可以创建可在未来任意时间使用的 DPoP 证明。

在 DPoP 证明中包含由授权服务器贡献的 nonce 值, 授权服务器 MAY 用其限制 DPoP 证明的生命周期。 服务器决定何时发出新的 DPoP nonce 质询以及是否 需要该质询,从而要求在后续 DPoP 证明中 使用该 nonce 值。 服务器作出该决定的逻辑超出本文档范围。

授权服务器 MAY 提供一个 nonce 值, 供客户端包含在所发送的 DPoP 证明中。在这种情况下,授权服务器会对不包含 nonce 的请求,按照 [RFC6749] 第 5.2 节 使用 use_dpop_nonce 作为 错误码值返回 HTTP 400 (Bad Request) 错误响应。授权服务器在响应中包含 DPoP-Nonce HTTP 标头,提供 一个在发送后续请求时使用的 nonce 值。Nonce 值 MUST 是不可预测的。 当由于 nonce 不匹配而提供新的 nonce 值时,也使用同一个错误码。 客户端在收到带有 accompanying nonce 值的 use_dpop_nonce 错误后, 通常会使用所提供的新 nonce 值重试该请求。

例如,当授权服务器要求 nonce,而令牌请求没有 nonce 时, 授权服务器可以用如下 DPoP-Nonce 值进行响应,以提供 要包含在 DPoP 证明中的 nonce 值:

 HTTP/1.1 400 Bad Request
 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v

 {
  "error": "use_dpop_nonce",
  "error_description":
    "Authorization server requires nonce in DPoP proof"
 }
图 20对没有 Nonce 的令牌请求的 HTTP 400 响应

错误响应中 MAY 还可以包含其他 HTTP 标头和 JSON 字段, 但 MUST NOT 存在多于一个 DPoP-Nonce 标头。

收到 nonce 后,客户端应使用一个 DPoP 证明重试其令牌请求, 该证明在 DPoP 证明的 nonce 声明中包含所提供的 nonce 值。 下方显示了一个包含 nonce 的此类 DPoP 证明的未编码 JWT 载荷示例。

 {
  "jti": "-BwC3ESc6acc2lTc",
  "htm": "POST",
  "htu": "https://server.example.com/token",
  "iat": 1562262616,
  "nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v"
 }
图 21包含 Nonce 值的 DPoP 证明载荷

Nonce 对客户端是不透明的。

如果 DPoP 证明中的 nonce 声明 与授权服务器最近提供给客户端的 nonce 不完全匹配, 授权服务器 MUST 拒绝该请求。 拒绝响应 MAY 包含一个 DPoP-Nonce HTTP 标头, 提供一个用于后续请求的新 nonce 值。

其意图是客户端只需要保留一个 nonce 值,而服务器需要保留一个 最近 nonce 的窗口。 也就是说,可能会出现一些短暂情况,使服务器和客户端 存储的 nonce 值不同。 不过,这种情况会自我修正。 对于任何拒绝消息, 服务器都可以将它希望使用的 nonce 值发送给客户端, 客户端则可以存储该 nonce 值并用它重试请求。 即使客户端和/或服务器丢弃了它们存储的 nonce 值, 这种情况也会自我修正,因为在响应或重试失败请求时 可以传达新的 nonce 值。

注意,使用 CORS [WHATWG.Fetch] 的基于浏览器的客户端应用 默认只能访问 CORS 安全列出的响应 HTTP 标头。 为了让应用获取并使用 DPoP-Nonce HTTP 响应标头 值,服务器需要通过将 DPoP-Nonce 包含在 Access-Control-Expose-Headers 响应标头列表值中, 使其可供应用访问。

8.1. Nonce 语法

下方显示了 [RFC6749] 所使用的 ABNF 中的 nonce 语法 (它与 scope-token 语法相同)。

nonce = 1*NQCHAR
图 22Nonce ABNF

8.2. 提供新的 Nonce 值

何时为客户端提供新的 nonce 值由授权服务器决定。 客户端应在 DPoP 证明中使用现有已提供的 nonce, 直到服务器提供新的 nonce 值。

授权服务器 MAY 以提供初始 nonce 的相同方式提供新的 nonce: 通过在响应中使用 DPoP-Nonce HTTP 标头。 DPoP-Nonce HTTP 标头字段使用 第 8.1 节 中定义的 nonce 语法。 每次这样做时,都需要一次额外的协议往返。

还定义了一种更高效的提供新 nonce 值的方式, 即在上一个请求的 HTTP 200 (OK) 响应中 包含 DPoP-Nonce HTTP 标头。 客户端 MUST 将所提供的新 nonce 值用于下一个令牌 请求以及所有后续令牌请求,直到授权服务器 提供新的 nonce。

包含 DPoP-Nonce HTTP 标头的响应应当是 不可缓存的 (例如,在响应 GET 请求时使用 Cache-Control: no-store), 以防止该响应被用于服务后续请求,并因此使用陈旧的 nonce 值。

下方显示了一个提供新 nonce 值的 200 OK 响应示例。

 HTTP/1.1 200 OK
 Cache-Control: no-store
 DPoP-Nonce: eyJ7S_zG.eyJbYu3.xQmBj-1
图 23提供下一个 Nonce 值的 HTTP 200 响应

9. 资源服务器提供的 Nonce

资源服务器也可以选择提供一个 nonce 值, 供发送给它们的 DPoP 证明包含。 它们使用 DPoP-Nonce 标头来提供 nonce,方式与授权服务器在 第 8 节第 8.2 节 中所述的方式相同。 错误信号按 第 7.1 节 中所述执行。 资源服务器使用 HTTP 401 (Unauthorized) 错误码, 并伴随 WWW-Authenticate: DPoP 值 和 DPoP-Nonce 值来完成此操作。

例如,当资源服务器要求 nonce,而资源请求没有 nonce 时, 资源服务器可以用如下 DPoP-Nonce 值进行响应,以提供 要包含在 DPoP 证明中的 nonce 值。 下方示例根据 [RFC8792] 使用 “\” 换行。

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: DPoP error="use_dpop_nonce", \
   error_description="Resource server requires nonce in DPoP proof"
 DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
图 24对没有 Nonce 的资源 请求的 HTTP 401 响应

注意,授权服务器和资源服务器提供的 nonce 是不同的, 不应相互混淆, 因为 nonce 只会被签发它们的服务器接受。 同样,如果客户端使用多个授权服务器和/或资源服务器, 其中任何服务器签发的 nonce 都应只在签发服务器处使用。 开发者还应注意不要将 DPoP nonce 与 OpenID Connect [OpenID.Core] ID Token nonce 混淆。

10. 授权码绑定到 DPoP 密钥

将签发给客户端的授权码绑定到客户端的持有证明密钥, 可以实现整个授权流程的端到端绑定。 本规范为此定义了 dpop_jkt 授权请求参数。 dpop_jkt 授权请求参数的值是 持有证明公钥的 JWK Thumbprint [RFC7638], 使用 SHA-256 哈希函数计算, 该值与 第 6.1 节 中定义的 jkt 确认方法所使用的值相同。

收到令牌请求时,授权服务器会计算 DPoP 证明中 持有证明公钥的 JWK Thumbprint, 并验证它是否与授权请求中的 dpop_jkt 参数值匹配。 如果不匹配,它 MUST 拒绝该请求。

下方显示了一个使用 dpop_jkt 授权请求 参数的授权请求示例,并根据 [RFC8792] 使用 “\” 换行。

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz\
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM\
    &code_challenge_method=S256\
    &dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1
Host: server.example.com
图 25使用 dpop_jkt 参数的授权请求

dpop_jkt 授权请求参数的使用是 OPTIONAL 的。 注意,dpop_jkt 授权请求参数 MAY 还可以 与 Proof Key for Code Exchange (PKCE) [RFC7636] 结合使用,后者由 [SECURITY-TOPICS] 推荐作为授权码注入的对策。dpop_jkt 授权 请求参数只有在每个授权请求都使用唯一 DPoP 密钥时, 才提供类似保护。

10.1. DPoP 与推送 授权请求

当 Pushed Authorization Requests (PARs) [RFC9126] 与 DPoP 结合使用时,有两种 方式可以在 PAR 请求中传达 DPoP 密钥:

  • dpop_jkt 参数可按 第 10 节 中所述使用,以将所签发的 授权码绑定到特定密钥。在这种情况下,dpop_jkt MUST 与其他授权请求参数一起包含在 PAR 请求的 POST 主体中。
  • 或者,可以将 DPoP 标头 添加到 PAR 请求中。在这种 情况下,授权服务器 MUST 按照 第 4.3 节 中定义检查所提供的 DPoP 证明 JWT。它还 MUST 表现得如同所包含公钥的 指纹是使用 dpop_jkt 提供的一样,即拒绝后续令牌 请求,除非提供同一密钥的 DPoP 证明。这有助于 简化客户端实现,因为它可以“盲目地”将 DPoP 标头附加到发送给授权服务器的所有请求,而不管请求 类型如何。此外,它提供了更强的绑定,因为 DPoP 标头包含私钥持有证明。

同时支持 PAR 和 DPoP 的授权服务器 MUST 支持这两种机制。如果两种机制同时使用, 当 dpop_jkt 中的 JWK Thumbprint 与 DPoP 标头中的公钥不匹配时, 授权服务器 MUST 拒绝该请求。

允许这两种机制可以确保使用 dpop_jkt 的客户端 不需要区分前信道授权请求和推送授权请求,同时, 只有一条代码路径来保护所有对授权服务器端点调用的客户端 也不需要区分发送给 PAR 端点的请求和 令牌端点请求。

11. 安全注意事项

在 DPoP 中,防止令牌在不同端点重放(见 第 2 节)是通过按照 [RFC6125] 对 服务器进行认证,以及将 DPoP 证明绑定到特定 URI 和 HTTP 方法来实现的。不过,DPoP 的保护性质与基于 TLS 的 方法(例如 OAuth Mutual TLS [RFC8705] 或 OAuth Token Binding [TOKEN-BINDING])有所不同 (另见 第 11.1 节第 11.7 节)。 基于 TLS 的机制可以利用 TLS 层与应用层之间的紧密集成, 以实现强 消息完整性、真实性 和重放保护。

11.1. DPoP 证明重放

如果对手能够获得 DPoP 证明 JWT,则该对手 可以在同一端点重放该令牌(HTTP 端点 和方法通过 JWT 中相应声明强制执行)。为了 限制这种情况,服务器 MUST 仅在 DPoP 证明创建后的有限时间内 接受它们(最好只接受相对较短的一段时间, 以秒或分钟为量级)。

在目标 URI 的上下文中,服务器可以在相应 DPoP 证明 JWT 可被接受的时间窗口内,存储每个 DPoP 证明的 jti 值,以防止同一个 DPoP 证明被多次使用。 对同一 URI 的 HTTP 请求,如果其 jti 值之前已出现, 将被拒绝。严格执行时,这种一次性使用检查可针对 DPoP 证明重放提供非常强的保护,但在实践中可能并不总是可行, 例如,当单个端点后面的多个服务器没有共享状态时。

为了防范 内存耗尽攻击,跟踪 jti 值的服务器应拒绝带有不必要的大型 jti 值的 DPoP 证明 JWT,或只存储其哈希。

注意:为适应时钟偏移,服务器 MAY 接受携带合理近未来(以秒或分钟为量级) iat 时间的 DPoP 证明。 由于服务器与客户端之间的时钟偏差可能很大, 服务器 MAY 通过使用包含服务器时间的 服务器提供 nonce 值来限制 DPoP 证明生命周期,而不是 将客户端提供的 iat 时间与服务器时间进行比较。以这种方式 创建的 nonce 即使面对任意大的时钟偏差,也会得到相同结果。

服务器提供的 nonce 是进一步降低 DPoP 证明重放成功概率的 有效手段。 与加密 nonce 不同,客户端多次使用同一个 nonce、服务器多次接受同一个 nonce 是可以接受的。 只要跟踪 jti 值并在 nonce 生命周期内拒绝重复项, 就不会有额外的令牌重放风险。

11.2. DPoP 证明 预生成

控制客户端的攻击者可以通过选择 DPoP 证明中的 iat 值,并用持有证明密钥对其签名, 为特定端点预生成可在未来任意时间使用的 DPoP 证明。 注意,一个这样的攻击者可能就是客户端的合法用户。 用户可以预生成 DPoP 证明, 并将其从拥有持有证明密钥的机器中窃取出来, 然后复制到另一台不拥有该密钥的机器上。 例如,银行员工可能在银行计算机上预生成 DPoP 证明, 然后将其复制到另一台机器 以便将来使用,从而绕过银行审计控制。 当 DPoP 证明可以被预生成并窃取时, DPoP 协议交互中实际证明的只是持有 DPoP 证明, 而不是持有持有证明密钥。

使用攻击者无法预测的服务器提供 nonce 值, 可以防止这种攻击。 通过在服务器选择的时间提供新的 nonce 值, 服务器可以限制 DPoP 证明的生命周期, 防止预生成的 DPoP 证明被使用。 使用服务器提供的 nonce 时,所证明的是 持有持有证明密钥, 而不仅仅是持有 DPoP 证明。

ath 声明将预生成 DPoP 证明的使用限制在 访问令牌的生命周期内。不使用 nonce 机制的部署 SHOULD NOT 签发长期有效的 DPoP 约束访问令牌, 而应优先使用短期访问令牌和刷新令牌。 虽然攻击者可以预生成 DPoP 证明来使用刷新令牌 获取新的访问令牌,但他们无法现实地 预生成 DPoP 证明来使用新签发的访问令牌。

11.3. DPoP Nonce 降级

当已向客户端提供 DPoP nonce 时,服务器 MUST NOT 接受任何不带 nonce 声明的 DPoP 证明。

11.4. 客户端上下文中的 不受信任代码

如果对手能够在客户端的执行上下文中运行代码, 则 DPoP 的安全性不再得到保证。Web 应用中导致执行不受信任代码的常见问题包括 XSS 和远程代码包含 攻击。

如果 DPoP 使用的私钥以 不能导出的方式存储,例如存储在硬件或软件安全模块中, 对手无法窃取该密钥并用它创建任意 DPoP 证明。然而,只要客户端在线, 对手就可以创建新的 DPoP 证明,并在受害者设备上或攻击者控制的设备上 将这些证明(连同相应令牌)用于发送任意请求, 这些请求将被服务器接受。

为了在客户端离线时也发送请求,对手可以尝试 使用未来时间戳预先计算 DPoP 证明,并将这些证明 与访问令牌或刷新令牌一起窃取。

对手还可能尝试将令牌端点签发的令牌 与对手控制的密钥对关联起来。一种 实现方式是修改现有代码,例如替换 加密 API。另一种方式是在 iframe 中在客户端和授权服务器之间 发起新的授权授予。该 授予需要是“静默的”,即不需要与 用户交互。由于代码在客户端的源中运行,对手可以 访问生成的授权码,并可用它将自己的 DPoP 密钥 与令牌端点返回的令牌关联起来。 即使客户端离线,对手随后也能够在自己的 设备上使用生成的令牌。

因此,即使使用了 DPoP,保护客户端不执行不受信任代码 也极其重要。除安全编码 实践之外,Content Security Policy [W3C.CSP] 可作为防御 XSS 的第二 层。

11.5. 已签名 JWT 交换

接受已签名 DPoP 证明 JWT 的服务器 MUST 验证 JWT 标头中的 typ 字段为 dpop+jwt, 以确保对手不能使用为其他目的创建的 JWT。

11.6. 签名算法

实现者 MUST 确保只有被认为安全的 非对称数字签名算法(例如 ES256) 可用于签署 DPoP 证明。特别是, 算法 none MUST NOT 被允许。

11.7. 请求完整性

DPoP 不确保请求载荷或标头的完整性。 DPoP 证明只包含 HTTP URI 和方法的声明, 但不包含消息主体或一般请求 标头等内容。

这是一个有意的设计决定,旨在让 DPoP 简单易用, 但如前所述,这使 DPoP 可能容易受到重放攻击, 即攻击者能够修改消息内容和标头。在 许多设置中,TLS 提供的消息完整性和机密性 足以提供良好的保护水平。

注意:虽然覆盖请求其他部分的签名超出了 本规范的范围, 但可以将要签名的其他信息 添加到 DPoP 证明中。

11.8. 访问令牌与 公钥绑定

第 6 节 所规定,访问令牌与 DPoP 公钥的绑定使用 公钥的 JWK 表示形式的加密哈希。它依赖于 哈希函数具有足够的第二原像抗性, 使得找到或创建另一个产生相同哈希输出值的 密钥在计算上不可行。之所以使用 SHA-256 哈希函数,是因为它满足上述 要求且广泛可用。

类似地,DPoP 证明与访问令牌的绑定使用 该访问令牌的哈希作为 DPoP 证明中 ath 声明的值 (见 第 4.2 节)。 这依赖于哈希值 足够唯一,以便可靠地识别 访问令牌。SHA-256 的抗碰撞性满足该要求。

11.9. 授权码与 公钥绑定

授权码与 DPoP 公钥的加密绑定 在 第 10 节 中规定。 这种绑定可防止攻击者捕获 授权码,并使用客户端所持密钥以外的持有证明密钥 创建 DPoP 证明,然后使用该 DPoP 证明兑换授权码的攻击。 通过端到端确保只有客户端的 DPoP 密钥可以使用,这会防止捕获的授权码被 窃取并在授权码签发地点以外的位置使用。

例如,攻击者可以从记录包含授权码的 HTTP 消息的位置 收集授权码。 即使努力使授权码只能一次性使用,在实践中 通常仍存在攻击者可以重放它们的时间窗口。 例如,当授权服务器实现为可扩展的复制服务时, 某些副本可能暂时尚未拥有防止重放所需的信息。 授权码的 DPoP 绑定解决了这些问题。

如果授权服务器没有(或不能)严格执行授权码的 单次使用限制, 并且攻击者可以访问授权码(如果使用 PKCE,还包括 code_verifier), 则攻击者可以创建伪造的令牌请求,将生成的令牌绑定到 攻击者控制的密钥。 例如,攻击者可能使用 XSS 获得授权码和 PKCE 参数的访问权。 使用 dpop_jkt 参数可防止这种攻击。

授权码与 DPoP 公钥的绑定 使用公钥的 JWK Thumbprint,就像访问令牌绑定一样。 同样的 JWK Thumbprint 注意事项也适用。

11.10. 哈希算法敏捷性

本文定义的 jkt 确认方法成员、ath JWT 声明以及 dpop_jkt 授权 请求参数都使用 SHA-256 哈希函数的输出作为它们的值。 本规范使用单一哈希函数是有意为之,目的在于 简化,并避免由实现和部署参数化算法敏捷性方案时的 常见错误所导致的潜在安全和互操作性问题。 然而,如果未来情况发生变化,使 SHA-256 不足以满足本规范要求, 则不排除使用不同的哈希函数。 如果出现这种需要,预期会产生一个简短规范来 更新本规范。 通过使用适当 哈希函数的输出作为值,该规范可能会定义新的确认方法 成员、新的 JWT 声明 和新的授权请求参数。这些项将用于替代或并列于 本规范所定义较大协议的相同消息结构和流程中 各自的对应项。

11.11. 绑定到客户端 身份

在 DPoP 与客户端认证一起使用的情况下,它仅通过 同时存在于同一个 TLS 隧道中而绑定到认证。由于 DPoP 证明并未 以加密方式直接绑定到认证, 认证或 DPoP 消息可能被复制进 该隧道。虽然在 DPoP 中包含 URI 可以部分缓解这种风险, 但修改 认证机制以提供认证与 DPoP 之间的加密绑定 可以 提供更好的保护。然而,通过修改认证机制或其他方式 提供与认证的额外绑定超出了本 规范范围。

12. IANA 注意事项

12.1. OAuth 访问令牌 类型注册

IANA 已在由 [RFC6749] 建立的 “OAuth Access Token Types” 注册表 [IANA.OAuth.Params] 中注册以下访问令牌 类型。

名称:
DPoP
其他令牌端点响应参数:
(无)
HTTP 认证方案:
DPoP
变更控制者:
IETF
参考:
RFC 9449

12.2. OAuth 扩展错误 注册

IANA 已在由 [RFC6749] 建立的 “OAuth Extensions Error” 注册表 [IANA.OAuth.Params] 中注册以下错误值。

无效 DPoP 证明:


名称:
invalid_dpop_proof
使用位置:
令牌错误响应,资源 访问错误响应
协议扩展:
Demonstrating Proof of Possession (DPoP)
变更控制者:
IETF
参考:
RFC 9449
使用 DPoP nonce:


名称:
use_dpop_nonce
使用位置:
令牌错误响应,资源 访问错误响应
协议扩展:
Demonstrating Proof of Possession (DPoP)
变更控制者:
IETF
参考:
RFC 9449

12.3. OAuth 参数 注册

IANA 已在由 [RFC6749] 建立的 “OAuth Parameters” 注册表 [IANA.OAuth.Params] 中注册以下授权请求参数。

名称:
dpop_jkt
参数使用位置:
授权请求
变更控制者:
IETF
参考:
RFC 9449 第 10 节

12.4. HTTP 认证 方案注册

IANA 已在由 [RFC9110], 第 16.4.1 节 建立的 “HTTP Authentication Schemes” 注册表 [IANA.HTTP.AuthSchemes] 中注册以下方案。

认证方案名称:
DPoP
参考:
RFC 9449 第 7.1 节

12.5. 媒体类型 注册

IANA 已按 [RFC6838] 所述方式,在 “Media Types” 注册表 [IANA.MediaTypes] 中注册 application/dpop+jwt 媒体类型 [RFC2046], 其用于表示内容是 DPoP JWT。

类型名称:
application
子类型名称:
dpop+jwt
必需参数:
n/a
可选参数:
n/a
编码注意事项:
binary。DPoP JWT 是 JWT;JWT 值 被编码为一系列 base64url 编码值(其中一些可能为空字符串), 以句点 ('.') 字符分隔。
安全注意事项:
见 RFC 9449 第 11 节
互操作性注意事项:
n/a
已发布规范:
RFC 9449
使用此媒体类型的应用:
使用 RFC 9449 进行 应用层持有证明的应用
片段标识符注意事项:
n/a
附加信息:


文件扩展名:
n/a
Macintosh 文件类型代码:
n/a
联系人及电子邮件地址:
Michael B. Jones, michael_b_jones@hotmail.com
预期用途:
COMMON
使用限制:
作者:
Michael B. Jones, michael_b_jones@hotmail.com
变更控制者:
IETF

12.6. JWT 确认 方法注册

IANA 已在由 [RFC7800] 建立的 “JWT Confirmation Methods” 注册表 [IANA.JWT] 中注册以下 JWT cnf 成员值。

确认方法值:
jkt
确认方法描述:
JWK SHA-256 Thumbprint
变更控制者:
IETF
参考:
RFC 9449 第 6 节

12.7. JSON Web Token 声明 注册

IANA 已在由 [RFC7519] 建立的 “JSON Web Token Claims” 注册表 [IANA.JWT] 中注册以下声明。

HTTP 方法:


声明名称:
htm
声明描述:
请求的 HTTP 方法
变更控制者:
IETF
参考:
RFC 9449 第 4.2 节
HTTP URI:


声明名称:
htu
声明描述:
请求的 HTTP URI (不含查询和片段部分)
变更控制者:
IETF
参考:
RFC 9449 第 4.2 节
访问令牌哈希:


声明名称:
ath
声明描述:
关联访问令牌值的 ASCII 编码的 SHA-256 哈希经过 base64url 编码后的结果
变更控制者:
IETF
参考:
RFC 9449 第 4.2 节

12.7.1. "nonce" 注册更新

Internet Security Glossary [RFC4949] 给出了 nonce 的一个有用定义: 它是包含在协议交换数据中的随机值或非重复值, 通常用于保证活性, 从而检测和防止重放攻击。

然而,[OpenID.Core]nonce 声明的初始注册使用了 对该应用具有上下文特定性的语言, 这可能限制了其一般适用性。

因此,IANA 已更新 “JSON Web Token Claims” 注册表 [IANA.JWT]nonce 的条目, 以扩展后的定义反映该声明可在其他上下文中适当使用,并增加本文档 作为参考,如下所示。

声明名称:
nonce
声明描述:
用于将客户端 会话与 ID Token 关联的值(MAY 也用于 JWT 其他应用中的 nonce 值)
变更控制者:
OpenID Foundation Artifact Binding Working Group, openid-specs-ab@lists.openid.net
规范文档:
[OpenID.Core] 第 2 节 和 RFC 9449

12.8. 超文本传输 协议 (HTTP) 字段名称注册

IANA 已将本文档规定的以下 HTTP 标头字段注册到 由 [RFC9110] 建立的 “Hypertext Transfer Protocol (HTTP) Field Name Registry” [IANA.HTTP.Fields] 中:

DPoP:


字段名称:
DPoP
状态:
永久
参考:
RFC 9449
DPoP-Nonce:


字段名称:
DPoP-Nonce
状态:
永久
参考:
RFC 9449

12.9. OAuth 授权 服务器元数据注册

IANA 已在由 [RFC8414] 建立的 “OAuth Authorization Server Metadata” 注册表 [IANA.OAuth.Params] 中注册以下值。

元数据名称:
dpop_signing_alg_values_supported
元数据描述:
包含支持用于 DPoP 证明 JWT 的 JWS 算法列表的 JSON 数组
变更控制者:
IETF
参考:
RFC 9449 第 5.1 节

12.10. OAuth 动态客户端 注册元数据

IANA 已在由 [RFC7591] 建立的 IANA “OAuth Dynamic Client Registration Metadata” 注册表 [IANA.OAuth.Params] 中注册以下值。

客户端元数据名称:
dpop_bound_access_tokens
客户端元数据描述:
指定客户端是否 始终对令牌请求使用 DPoP 的布尔值
变更控制者:
IETF
参考:
RFC 9449 第 5.2 节

13. 参考文献

13.1. 规范性引用

[RFC2119]
Bradner, S., "RFC 中用于 表示要求级别的关键词", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "统一资源标识符 (URI):通用语法", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5234]
Crocker, D., Ed. and P. Overell, "语法规范的扩展 BNF:ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, , <https://www.rfc-editor.org/info/rfc5234>.
[RFC6125]
Saint-Andre, P. and J. Hodges, "在传输层安全 (TLS) 上下文中使用 X.509 (PKIX) 证书的互联网公钥基础设施内, 基于域的应用服务身份的表示与验证", RFC 6125, DOI 10.17487/RFC6125, , <https://www.rfc-editor.org/info/rfc6125>.
[RFC6749]
Hardt, D., Ed., "OAuth 2.0 授权 框架", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "OAuth 2.0 授权框架:Bearer Token 用法", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC7517]
Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, , <https://www.rfc-editor.org/info/rfc7517>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC7638]
Jones, M. and N. Sakimura, "JSON Web Key (JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, , <https://www.rfc-editor.org/info/rfc7638>.
[RFC7800]
Jones, M., Bradley, J., and H. Tschofenig, "JSON Web Token (JWT) 的 持有证明密钥语义", RFC 7800, DOI 10.17487/RFC7800, , <https://www.rfc-editor.org/info/rfc7800>.
[RFC8174]
Leiba, B., "RFC 2119 关键词中大写与 小写的歧义", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[SHS]
National Institute of Standards and Technology, "Secure Hash Standard (SHS)", FIPS PUB 180-4, DOI 10.6028/NIST.FIPS.180-4, , <http://dx.doi.org/10.6028/NIST.FIPS.180-4>.

13.2. 资料性引用

[BREACH]
CVE, "CVE-2013-3587", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3587>.
[Cloudbleed]
Graham-Cumming, J., "Cloudflare 解析器 bug 导致内存 泄漏的事件报告", , <https://blog.cloudflare.com/incident-report-on-memory-leak-caused-by-cloudflare-parser-bug/>.
[CRIME]
CVE, "CVE-2012-4929", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-4929>.
[GitHub.Tokens]
Hanley, M., "安全警报:涉及发给两个第三方集成方的被盗 OAuth 用户令牌的 攻击活动", , <https://github.blog/2022-04-15-security-alert-stolen-oauth-user-tokens/>.
[Heartbleed]
"CVE-2014-0160", <https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2014-0160>.
[IANA.HTTP.AuthSchemes]
IANA, "超文本传输协议 (HTTP) 认证方案注册表", <https://www.iana.org/assignments/http-authschemes/>.
[IANA.HTTP.Fields]
IANA, "超文本传输协议 (HTTP) 字段名称注册表", <https://www.iana.org/assignments/http-fields/>.
[IANA.JOSE.ALGS]
IANA, "JSON Web Signature and Encryption Algorithms", <https://www.iana.org/assignments/jose/>.
[IANA.JWT]
IANA, "JSON Web Token Claims", <https://www.iana.org/assignments/jwt/>.
[IANA.MediaTypes]
IANA, "媒体类型", <https://www.iana.org/assignments/media-types/>.
[IANA.OAuth.Params]
IANA, "OAuth 参数", <https://www.iana.org/assignments/oauth-parameters/>.
[OpenID.Core]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0 incorporating errata set 1", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[RFC2046]
Freed, N. and N. Borenstein, "多用途互联网邮件扩展 (MIME) 第二部分:媒体类型", RFC 2046, DOI 10.17487/RFC2046, , <https://www.rfc-editor.org/info/rfc2046>.
[RFC4122]
Leach, P., Mealling, M., and R. Salz, "通用唯一标识符 (UUID) URN 命名空间", RFC 4122, DOI 10.17487/RFC4122, , <https://www.rfc-editor.org/info/rfc4122>.
[RFC4949]
Shirey, R., "互联网安全术语表, 第 2 版", FYI 36, RFC 4949, DOI 10.17487/RFC4949, , <https://www.rfc-editor.org/info/rfc4949>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "媒体类型规范和 注册程序", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC7523]
Jones, M., Campbell, B., and C. Mortimore, "用于 OAuth 2.0 客户端认证和授权授予的 JSON Web Token (JWT) 配置文件", RFC 7523, DOI 10.17487/RFC7523, , <https://www.rfc-editor.org/info/rfc7523>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 动态客户端注册 协议", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "OAuth 公共客户端的 Proof Key for Code Exchange", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/info/rfc7662>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 授权服务器 元数据", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 互 TLS 客户端认证和证书绑定访问 令牌", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "OAuth 2.0 的资源指示符", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC8725]
Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token 最佳当前 实践", BCP 225, RFC 8725, DOI 10.17487/RFC8725, , <https://www.rfc-editor.org/info/rfc8725>.
[RFC8792]
Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, "Internet-Draft 和 RFC 内容中长行的处理", RFC 8792, DOI 10.17487/RFC8792, , <https://www.rfc-editor.org/info/rfc8792>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP 语义", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9126]
Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 推送授权 请求", RFC 9126, DOI 10.17487/RFC9126, , <https://www.rfc-editor.org/info/rfc9126>.
[SECURITY-TOPICS]
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "OAuth 2.0 安全最佳当前实践", 进行中的工作, Internet-Draft, draft-ietf-oauth-security-topics-23, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-23>.
[TOKEN-BINDING]
Jones, M., Campbell, B., Bradley, J., and W. Denniss, "OAuth 2.0 Token Binding", 进行中的 工作, Internet-Draft, draft-ietf-oauth-token-binding-08, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-binding-08>.
[W3C.CSP]
West, M., "Content Security Policy Level 3", W3C 工作草案, , <https://www.w3.org/TR/CSP3/>.
[W3C.WebCryptoAPI]
Watson, M., "Web Cryptography API", W3C 推荐标准, , <https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126>.
[WHATWG.Fetch]
WHATWG, "Fetch 现行标准", , <https://fetch.spec.whatwg.org/>.

致谢

我们感谢 Brock AllenAnnabelle BackmanDominick BaierSpencer BaloghVittorio BertocciJeff CorriganDomingos CreadoPhilippe De RyckAndrii DeinegaWilliam DennissVladimir DzhuvinovMike EnganNikos FotiouMark HaineDick HardtJoseph HeenanBjorn HjelmJacob IdeskogJared JenningsBenjamin KadukPieter KasselmanNeil MaddenRohan MahyKarsten Meyer zu SelhausenNicolas MoraSteinar NoemMark NottinghamRob OttoAaron PareckiMichael PeckRoberto PolliPaul QuernaJustin RicherJoseph SaloweyRifaat Shekh-YusefFilip SkokanDmitry TeleginDave TongeJim Willeke 以及其他人为这项工作提供的宝贵意见、反馈和总体支持。

本文档源自德国斯图加特第 4 届 OAuth Security Workshop 上的讨论。我们感谢本 workshop 的组织者(Ralf KüstersGuido Schmitz)。

作者地址

Daniel Fett
Authlete
Brian Campbell
Ping Identity
John Bradley
Yubico
Torsten Lodderstedt
Tuconic
Michael Jones
Self-Issued Consulting
David Waite
Ping Identity