RFC 9126 OAuth PAR 2021年9月
Lodderstedt 等 标准轨道 [页]
流:
互联网工程任务组(IETF)
RFC:
9126
类别:
标准轨道
发布:
ISSN:
2070-1721
作者:
T. Lodderstedt
yes.com
B. Campbell
Ping Identity
N. Sakimura
NAT.Consulting
D. Tonge
Moneyhub Financial Technology
F. Skokan
Auth0

RFC 9126

OAuth 2.0 推送授权请求

摘要

本文档定义了推送授权请求(PAR)端点,该端点允许 客户端通过直接请求将 OAuth 2.0 授权请求的有效载荷推送到 授权服务器,并为它们提供 一个请求 URI,该 URI 用作在 后续调用授权端点时对数据的引用。

本备忘录状态

这是一个互联网标准轨道文档。

本文档是互联网工程任务组 (IETF)的产物。它代表了 IETF 社区的共识。它已经 过公开审查,并已由 互联网工程指导组(IESG)批准发布。关于 互联网标准的更多信息可参见 RFC 7841 第 2 节。

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

目录

1. 引言

本文档定义了推送授权请求(PAR)端点,它使 OAuth [RFC6749] 客户端 能够将授权请求的有效载荷直接推送到 授权服务器。作为交换会收到一个请求 URI 值;该值用作 授权请求有效载荷数据的引用,供随后通过用户代理调用授权端点时使用 。

在 OAuth [RFC6749] 中,授权 请求参数通常作为 URI 查询 参数通过用户代理中的重定向发送。这很简单,但也带来了一些挑战:

JWT 安全授权请求(JAR)[RFC9101] 通过允许 OAuth 客户端将授权请求参数包装在 Request Object 中,为这些安全挑战提供了解决方案;Request Object 是 一个已签名且可选加密的 JSON Web Token(JWT)[RFC7519]。 为了应对大小限制,JAR 引入了 request_uri 参数,允许客户端 发送对 Request Object 的引用,而不是发送 Request Object 本身。

本文档通过提供一种可互操作的方式来补充 JAR,使得 授权请求的有效载荷可以直接推送到授权服务器,以换取一个 可在后续授权请求中用于授权服务器的 request_uri 值。

PAR 通过为客户端提供一种简单方式来实现机密且 受完整性保护的授权请求,从而增强 OAuth 安全性。需要更高安全级别的客户端,尤其是 需要以密码学方式确认的不可否认性的客户端,能够按 [RFC9101] 中定义的方式结合 PAR 使用基于 JWT 的 Request Object。

PAR 允许授权服务器在任何用户 交互发生之前对客户端进行认证。 在授权过程中对客户端身份的信心提高,使 授权服务器能够在流程中更早拒绝非法请求,这可以防止 伪装客户端,或以其他方式篡改或滥用授权请求的企图。

注意,如 [RFC6749] 第 3.1 节[OIDC] 第 3.1.2.1 节所述,也可以使用经由用户代理 发往授权端点的 HTTP POST 请求来应对上述 请求大小限制。然而,根据 [RFC6749],这只是可选的;即使被支持,它对 传统 Web 应用而言是可行选项,但对已安装的移动应用来说使用起来极其困难。 如 [RFC8252] 所述,这些应用使用 平台特定 API 在系统浏览器中打开授权请求 URI。然而,当移动应用 启动浏览器时,生成的初始请求被限制为使用 GET 方法。使用 POST 发出授权请求将要求应用首先让 浏览器通过 GET 打开一个由应用控制的 URI,同时以某种方式传递庞大的 授权请求有效载荷,然后让生成的响应包含用于 向授权服务器发起跨站表单 POST 的内容和脚本。PAR 更易于使用, 并且如上所述具有额外的安全优势。

1.1. 引导性示例

在传统 OAuth 2.0 中,客户端通常通过 指示用户代理向授权服务器的授权端点发出类似下面的 HTTP 请求, 来发起授权 请求(额外的换行和缩进仅用于显示 目的):

 GET /authorize?response_type=code
  &client_id=CLIENT1234&state=duk681S8n00GsJpe7n9boxdzen
  &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
 Host: as.example.com

客户端可以改为通过 POST 请求将此类请求直接推送到授权服务器的 PAR 端点,如下面的 示例所示(额外的换行和空格仅用于显示目的)。 客户端可以进行认证(例如,如示例中所示使用基于 JWT 客户端断言的认证), 因为该请求是直接发往授权服务器的。

 POST /as/par HTTP/1.1
 Host: as.example.com
 Content-Type: application/x-www-form-urlencoded

 &response_type=code
 &client_id=CLIENT1234&state=duk681S8n00GsJpe7n9boxdzen
 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
 &client_assertion_type=
  urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
 &client_assertion=eyJraWQiOiI0MiIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJDTE
  lFTlQxMjM0Iiwic3ViIjoiQ0xJRU5UMTIzNCIsImF1ZCI6Imh0dHBzOi8vc2VydmVyL
  mV4YW1wbGUuY29tIiwiZXhwIjoxNjI1ODY4ODc4fQ.Igw8QrpAWRNPDGoWGRmJumLBM
  wbLjeIYwqWUu-ywgvvufl_0sQJftNs3bzjIrP0BV9rRG-3eI1Ksh0kQ1CwvzA

授权服务器以一个请求 URI 作为响应:

 HTTP/1.1 201 Created
 Cache-Control: no-cache, no-store
 Content-Type: application/json

 {
   "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2",
   "expires_in": 90
 }

客户端使用该请求 URI 值来创建后续授权 请求,方式是指示用户代理向授权服务器的 授权端点发出类似下面的 HTTP 请求(额外的换行和缩进仅用于显示 目的):

 GET /authorize?client_id=CLIENT1234
  &request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1
 Host: as.example.com

1.2. 约定和 术语

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

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

2. 推送授权请求端点

推送授权请求端点是授权服务器上的一个 HTTP API, 它接受 HTTP POST 请求,请求参数位于 HTTP 请求消息体中,并使用 application/x-www-form-urlencoded 格式。该格式的字符编码为 UTF-8,如 [RFC6749] 附录 B 中所述。PAR 端点 URL MUST 使用“https”方案。

支持 PAR 的授权服务器 SHOULD 在其 授权服务器元数据文档 [RFC8414] 中包含 其推送授权请求端点的 URL,使用 pushed_authorization_request_endpoint 参数,如 第 5 节 所定义。

该端点接受 [RFC6749] 中为授权端点定义的授权请求参数,以及 为授权端点定义的所有适用扩展。此类扩展的一些示例包括 Proof Key for Code Exchange(PKCE)[RFC7636]、Resource Indicators [RFC8707] 和 OpenID Connect(OIDC) [OIDC]。该端点 MAY 还支持 按照 [RFC9101] 和本文档 第 3 节,将授权请求参数集作为 Request Object 发送。

[RFC6749] 中为令牌端点请求定义的客户端认证规则,包括适用的 认证方法,也适用于 PAR 端点。如适用, token_endpoint_auth_method 客户端元数据参数 [RFC7591] 指示客户端在向授权服务器发出直接请求(包括 发往 PAR 端点的请求)时要使用的已注册认证方法。 类似地,token_endpoint_auth_methods_supported 授权服务器元数据 [RFC8414] 参数列出了授权服务器在接受来自客户端的 直接请求(包括发往 PAR 端点的请求)时支持的客户端认证方法。

由于历史原因,在使用基于 JWT 客户端断言的认证(在 [RFC7523] 第 2.2 节 中定义,且根据 [OIDC] 第 9 节使用 private_key_jwtclient_secret_jwt 认证方法名称)时,关于应使用的适当 audience 值存在潜在歧义。为解决这种歧义,[RFC8414] 所规定的 授权服务器 issuer 标识符 URL SHOULD 用作 audience 的值。为促进 互操作性,授权服务器 MUST 接受其 issuer 标识符、 令牌端点 URL 或推送授权请求端点 URL,作为将其标识为预期 audience 的值。

2.1. 请求

客户端将构成授权请求的参数直接发送到 PAR 端点。典型参数集可能包括:client_idresponse_typeredirect_uriscopestatecode_challengecode_challenge_method,如下例所示。 然而,推送授权请求可以由任何适用于授权端点的参数组成, 包括 [RFC6749] 中定义的参数以及所有适用扩展。 request_uri 授权请求参数是一个例外,它 MUST NOT 被提供。

请求还会按给定客户端的需要,包含 客户端认证所需的任何其他参数(例如 client_secretclient_assertionclient_assertion_type)。这些参数 已定义并注册用于令牌端点,但仅适用于客户端 认证。当它们出现在推送授权请求中时,只依赖它们进行 客户端认证,而与授权请求本身无关。任何与客户端认证无关的令牌 端点参数,对推送授权请求均没有定义的含义。 client_id 参数在授权请求和令牌端点请求中具有相同 语义;作为必需的授权请求参数,它同样也是推送授权请求中的必需参数。

客户端构造 HTTP POST 请求的消息体, 其中参数以 x-www-form-urlencoded 格式表示,并使用 UTF-8 字符编码,如 [RFC6749] 附录 B 所述。如适用,客户端还会按照与令牌端点请求相同的规则, 将其认证凭据添加到请求头或请求体中。

以下示例对此进行了说明(消息 体中的额外换行仅用于显示目的):

 POST /as/par HTTP/1.1
 Host: as.example.com
 Content-Type: application/x-www-form-urlencoded

 response_type=code&state=af0ifjsldkj&client_id=s6BhdRkqt3
 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
 &code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U
 &code_challenge_method=S256&scope=account-information
 &client_assertion_type=
  urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
 &client_assertion=eyJraWQiOiJrMmJkYyIsImFsZyI6IlJTMjU2In0.eyJpc3Mi
  OiJzNkJoZFJrcXQzIiwic3ViIjoiczZCaGRSa3F0MyIsImF1ZCI6Imh0dHBzOi8vc
  2VydmVyLmV4YW1wbGUuY29tIiwiZXhwIjoxNjI1ODY5Njc3fQ.te4IdnP_DK4hWrh
  TWA6fyhy3fxlAQZAhfA4lmzRdpoP5uZb-E90R5YxzN1YDA8mnVdpgj_Bx1lG5r6se
  f5TlckApA3hahhC804dcqlE4naEmLISmN1pds2WxTMOUzZY8aKKSDzNTDqhyTgE-K
  dTb3RafRj7tdZb09zWs7c_moOvfVcQIoy5zz1BvLQKW1Y8JsYvdpu2AvpxRPbcP8W
  yeW9B6PL6_fy3pXYKG3e-qUcvPa9kan-mo9EoSgt-YTDQjK1nZMdXIqTluK9caVJE
  RWW0fD1Y11_tlOcJn-ya7v7d8YmFyJpkhZfm8x1FoeH0djEicXTixEkdRuzsgUCm6
  GQ

授权服务器 MUST 按如下方式处理请求:

  1. 以与令牌端点相同的方式认证客户端 ([RFC6749] 第 2.3 节)。
  2. 如果提供了 request_uri 授权 请求参数,则拒绝该请求。
  3. 像验证发送到授权端点的授权请求一样, 验证该推送请求。例如,授权服务器检查 重定向 URI 是否匹配为客户端配置的重定向 URI 之一,并且还检查 该客户端是否被授权访问其所请求的 scope。 这种验证允许授权服务器尽早拒绝未授权或欺诈性请求。 授权服务器 MAY 省略其在 处理推送请求时无法执行的验证步骤;然而,这些检查随后 MUST 在授权端点处理授权请求时执行。

授权服务器 MAY 允许具有 认证凭据的客户端在每个推送授权请求中建立每授权请求的重定向 URI。 如 第 2.4 节 更详细描述,这是可能的,因为与 [RFC6749] 不同,本规范使 授权服务器能够在实际授权请求执行之前认证客户端并验证客户端请求。

2.2. 成功响应

如果验证成功,服务器 MUST 生成一个请求 URI,并在响应中以 201 HTTP 状态码提供它。 以下参数作为顶层成员包含在 HTTP 响应的消息体中,使用 [RFC8259] 所定义的 application/json 媒体类型。

request_uri
与已提交的 授权请求对应的请求 URI。该 URI 是后续授权请求中相应请求 数据的单次使用引用。授权流程获取 授权请求数据的方式由授权服务器自行决定,并不在 本规范范围内。无需通过此 URI 将授权请求数据 提供给其他方。
expires_in
一个 JSON 数字,表示 请求 URI 的生存期,以秒为单位的正整数。请求 URI 生存期由 授权服务器自行决定,但通常会相对较短(例如,在 5 到 600 秒之间)。

request_uri 值的格式由 授权服务器自行决定,但它 MUST 包含某个使用 密码学强伪随机算法生成的部分,使得预测或猜测有效值在计算上不可行 (具体细节见 [RFC6749] 第 10.10 节)。授权服务器 MAY 使用 urn:ietf:params:oauth:request_uri:<reference-value> 形式构造 request_uri 值,其中 <reference-value> 是 URI 的随机部分,用来引用 相应的授权请求数据。

request_uriMUST 绑定到 提交该授权请求的客户端。

以下是这种响应的示例:

 HTTP/1.1 201 Created
 Content-Type: application/json
 Cache-Control: no-cache, no-store

 {
  "request_uri":
    "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c",
  "expires_in": 60
 }

2.3. 错误响应

授权服务器返回错误响应,其格式与 [RFC6749] 第 5.2 节 中为令牌端点错误响应指定的格式相同,使用其中适当的错误代码 或 [RFC6749] 第 4.1.2.1 节 中的错误代码。在那些 [RFC6749] 第 4.1.2.1 节 禁止使用错误自动重定向回请求客户端, 因而没有定义错误代码的情况下(例如,当请求因缺失、无效或不匹配的 重定向 URI 而失败时),可以使用 invalid_request 错误代码作为默认 错误代码。当某个 OAuth 扩展参与已推送的授权请求的 初始处理时,也可以使用该 OAuth 扩展定义的错误代码。由于 推送授权请求的初始处理不涉及资源所有者交互, 因此与用户交互相关的错误代码,例如 [OIDC] 中定义的 consent_required,绝不会返回。

如果客户端被授权服务器或客户端策略要求使用已签名的 Request Object(见 [RFC9101], 第 10.5 节),则授权服务器 MUST 仅接受符合 第 3 节 中给出定义的请求,并且 MUST 以 HTTP 状态码 400 和错误代码 invalid_request 拒绝任何其他请求。

除上述内容外,PAR 端点还可以使用以下 HTTP 状态码:

405:
如果请求未使用 POST 方法,授权服务器以 HTTP 405(Method Not Allowed)状态码响应。
413:
如果请求大小超出 授权服务器允许的上限,授权服务器以 HTTP 413(Payload Too Large)状态码响应。
429:
如果某一特定时间段内来自客户端的 请求数量超过授权服务器允许的数量, 授权服务器以 HTTP 429(Too Many Requests)状态码响应。

以下是来自 PAR 端点的错误响应示例:

 HTTP/1.1 400 Bad Request
 Content-Type: application/json
 Cache-Control: no-cache, no-store

 {
   "error": "invalid_request",
   "error_description":
     "The redirect_uri is not valid for the given client"
 }

2.4. 客户端 重定向 URI 的管理

OAuth 2.0 [RFC6749] 允许 客户端在某些情况下使用未注册的 redirect_uri 值,或允许 授权服务器对客户端在授权端点提交的 redirect_uri 值 应用其自己的匹配语义。然而,OAuth 安全 BCP [OAUTH-SECURITY-TOPICS] 以及 OAuth 2.1 规范 [OAUTH-V2] 要求授权服务器将 redirect_uri 参数与先前为特定客户端建立的一组重定向 URI 进行精确匹配。这是早期检测客户端冒充尝试的一种手段, 并可防止令牌泄露和开放重定向。缺点是,这会使客户端管理更加 繁琐,因为重定向 URI 通常是客户端策略中最易变的部分。

对于已与授权服务器建立认证凭据的客户端, 使用 PAR 时 MAY 放宽精确匹配要求。 这是可能的,因为与传统授权请求不同, 授权服务器会在授权流程开始之前认证客户端,从而 确保它正在与合法客户端交互。授权服务器 MAY 允许此类客户端指定 先前未向授权服务器注册的 redirect_uri 值。这将给予客户端更大的 灵活性(例如,在运行时为每个授权服务器铸造不同的 redirect_uri 值), 并可简化客户端管理。授权服务器可自行决定对所提供的 redirect_uri 值施加限制,例如,授权服务器 MAY 要求特定 URI 前缀,或只允许查询 参数在运行时变化。

3. “request” 请求参数

客户端 MAY 使用 JAR [RFC9101] 中定义的 request 参数,将 Request Object JWT 推送到 授权服务器。JAR [RFC9101] 中定义的 Request Object 处理、签名和加密规则 适用。给定客户端认证方法所需的请求参数会直接包含在 application/x-www-form-urlencoded 请求中,并且是表单体中除 request 之外的唯一参数(例如, mutual TLS 客户端认证 [RFC8705] 使用 client_id HTTP 请求参数,而基于 JWT 断言的客户端认证 [RFC7523] 使用 client_assertionclient_assertion_type)。所有其他请求参数,即与 授权请求本身相关的参数,MUST 作为表示 授权请求的 JWT 的声明出现。

以下是使用已签名 Request Object 的推送授权请求示例,其授权请求有效载荷与 第 2.1 节 中示例相同。客户端使用基于 JWT 客户端断言的 认证 [RFC7523] 进行认证(额外的换行和空格 仅用于显示目的):

 POST /as/par HTTP/1.1
 Host: as.example.com
 Content-Type: application/x-www-form-urlencoded

 client_assertion_type=
  urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
 &client_assertion=eyJraWQiOiJrMmJkYyIsImFsZyI6IlJTMjU2In0.eyJpc3Mi
  OiJzNkJoZFJrcXQzIiwic3ViIjoiczZCaGRSa3F0MyIsImF1ZCI6Imh0dHBzOi8vc
  2VydmVyLmV4YW1wbGUuY29tIiwiZXhwIjoxNjI1ODY5Njc3fQ.te4IdnP_DK4hWrh
  TWA6fyhy3fxlAQZAhfA4lmzRdpoP5uZb-E90R5YxzN1YDA8mnVdpgj_Bx1lG5r6se
  f5TlckApA3hahhC804dcqlE4naEmLISmN1pds2WxTMOUzZY8aKKSDzNTDqhyTgE-K
  dTb3RafRj7tdZb09zWs7c_moOvfVcQIoy5zz1BvLQKW1Y8JsYvdpu2AvpxRPbcP8W
  yeW9B6PL6_fy3pXYKG3e-qUcvPa9kan-mo9EoSgt-YTDQjK1nZMdXIqTluK9caVJE
  RWW0fD1Y11_tlOcJn-ya7v7d8YmFyJpkhZfm8x1FoeH0djEicXTixEkdRuzsgUCm6
  GQ
 &request=eyJraWQiOiJrMmJkYyIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJzNkJoZ
  FJrcXQzIiwiYXVkIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJleHAiOj
  E2MjU4Njk2NzcsInJlc3BvbnNlX3R5cGUiOiJjb2RlIiwiY2xpZW50X2lkIjoiczZ
  CaGRSa3F0MyIsInJlZGlyZWN0X3VyaSI6Imh0dHBzOi8vY2xpZW50LmV4YW1wbGUu
  b3JnL2NiIiwic2NvcGUiOiJhY2NvdW50LWluZm9ybWF0aW9uIiwic3RhdGUiOiJhZ
  jBpZmpzbGRraiIsImNvZGVfY2hhbGxlbmdlIjoiSzItbHRjODNhY2M0aDBjOXc2RV
  NDX3JFTVRKM2J3dy11Q0hhb2VLMXQ4VSIsImNvZGVfY2hhbGxlbmdlX21ldGhvZCI
  6IlMyNTYifQ.l9R3RC9bFBHry_8acObQjEf4fX5yfJkWUPfak3J3iiBm0aaQznPw5
  BZ0B3VQZ9_KYdPt5bTkaflS5fSDklM3_7my9MyOSKFYmf46INk6ju_qUuC2crkOQX
  ZWYJB-0bnYEbdHpUjazFSUvN49cEGstNQeE-dKDWHNgEojgcuNA_pjKfL9VYp1dEA
  6-WjXZ_OlJ7R_mBWpjFAzc0UkQwqX5hfOJoGTqB2tE4a4aB2z8iYlUJp0DeeYp_hP
  N6svtmdvte73p5bLGDFpRIlmrBQIAQuxiS0skORpXlS0cBcgHimXVnXOJG7E-A_lS
  _5y54dVLQPA1jKYx-fxbYSG7dp2fw
 &client_id=s6BhdRkqt3

第 2.1 节 中定义的处理规则之外, 授权服务器 MUST 采取以下步骤:

  1. 如适用,按 JAR [RFC9101], 第 6.1 节 中指定的方式解密 Request Object。
  2. 按 JAR [RFC9101], 第 6.2 节 中指定的方式验证 Request Object 签名。
  3. 如果客户端已与授权服务器建立认证凭据, 当已认证的 client_id 与 Request Object 中的 client_id 声明不匹配时,拒绝该请求。此外,是否要求 iss 声明与 client_id 匹配,由授权服务器自行决定。

以下 RSA 密钥对以 JSON Web Key(JWK)格式 [RFC7517] 表示, 可用于验证或重新创建上述示例中的 Request Object 签名(值中的额外换行和缩进仅用于 显示目的):

 {
   "kty": "RSA",
   "kid":"k2bdc",
   "n": "y9Lqv4fCp6Ei-u2-ZCKq83YvbFEk6JMs_pSj76eMkddWRuWX2aBKGHAtKlE
         5P7_vn__PCKZWePt3vGkB6ePgzAFu08NmKemwE5bQI0e6kIChtt_6KzT5Oa
         aXDFI6qCLJmk51Cc4VYFaxgqevMncYrzaW_50mZ1yGSFIQzLYP8bijAHGVj
         dEFgZaZEN9lsn_GdWLaJpHrB3ROlS50E45wxrlg9xMncVb8qDPuXZarvghL
         L0HzOuYRadBJVoWZowDNTpKpk2RklZ7QaBO7XDv3uR7s_sf2g-bAjSYxYUG
         sqkNA9b3xVW53am_UZZ3tZbFTIh557JICWKHlWj5uzeJXaw",
   "e": "AQAB",
   "d": "LNwG_pCKrwowALpCpRdcOKlSVqylSurZhE6CpkRiE9cpDgGKIkO9CxPlXOL
         zjqxXuQc8MdMqRQZTnAwgd7HH0B6gncrruV3NewI-XQV0ckldTjqNfOTz1V
         Rs-jE-57KAXI3YBIhu-_0YpIDzdk_wBuAk661Svn0GsPQe7m9DoxdzenQu9
         O_soewUhlPzRrTH0EeIqYI715rwI3TYaSzoWBmEPD2fICyj18FF0MPy_SQz
         k3noVUUIzfzLnnJiWy_p63QBCMqjRoSHHdMnI4z9iVpIwJWQ3jO5n_2lC2-
         cSgwjmKsFzDBbQNJc7qMG1N6EssJUwgGJxz1eAUFf0w4YAQ",
   "qi": "J-mG0swR4FTy3atrcQ7dd0hhYn1E9QndN-
         -sDG4EQO0RnFj6wIefCvwIc4
         7hCtVeFnCTPYJNc_JyV-mU-9vlzS5GSNuyR5qdpsMZXUMpEvQcwKt23ffPZ
         YGaqfKyEesmf_Wi8fFcE68H9REQjnniKrXm7w2-IuG_IrVJA9Ox-uU",
   "q": "4hlMYAGa0dvogdK1jnxQ7J_Lqpqi99e-AeoFvoYpMPhthChTzwFZO9lQmUo
         BpMqVQTws_s7vWGmt7ZAB3ywkurf0pV7BD0fweJiUzrWk4KJjxtmP_auuxr
         jvm3s2FUGn6f0wRY9Z8Hj9A7C72DnYCjuZiJQMYCWDsZ8-d-L1a-s",
   "p": "5sd9Er3I2FFT9R-gy84_oakEyCmgw036B_nfYEEOCwpSvi2z7UcIVK3bSEL
         5WCW6BNgB3HDWhq8aYPirwQnqm0K9mX1E-4xM10WWZ-rP3XjYpQeS0Snru5
         LFVWsAzi-FX7BOqBibSAXLdEGXcXa44l08iec_bPD3xduq5V_1YoE",
   "dq": "Nz2PF3XM6bEc4XsluKZO70ErdYdKgdtIJReUR7Rno_tOZpejwlPGBYVW19
         zpAeYtCT82jxroB2XqhLxGeMxEPQpsz2qTKLSe4BgHY2ml2uxSDGdjcsrbb
         NoKUKaN1CuyZszhWl1n0AT_bENl4bJgQj_Fh0UEsQj5YBBUJt5gr_k",
   "dp": "Zc877jirkkLOtyTs2vxyNe9KnMNAmOidlUc2tE_-0gAL4Lpo1hSwKCtKwe
         ZJ-gkqt1hT-dwNx_0Xtg_-NXsadMRMwJnzBMYwYAfjApUkfqABc0yUCJJl3
         KozRCugf1WXkU9GZAH2_x8PUopdNUEa70ISowPRh04HANKX4fkjWAE"
  }

4. 授权请求

客户端使用授权服务器返回的 request_uri 值, 构建 [RFC9101] 中定义的授权请求。如下例所示, 客户端指示用户代理发出以下 HTTP 请求(额外的换行和缩进仅用于显示 目的):

 GET /authorize?client_id=s6BhdRkqt3&request_uri=urn%3Aietf%3Aparams
  %3Aoauth%3Arequest_uri%3A6esc_11ACC5bwc014ltc14eY22c HTTP/1.1
 Host: as.example.com

由于授权请求内容的部分内容,例如 code_challenge 参数值,对于特定授权请求是唯一的,客户端 MUST 只使用一次 request_uri 值。授权服务器 SHOULDrequest_uri 值视为一次性使用,但 MAY 因用户重新加载/刷新其用户代理而允许重复请求。 已过期的 request_uri MUST 作为无效而被拒绝。

授权服务器 MUST 验证由推送请求产生的授权请求, 就像验证任何其他授权请求一样。授权服务器 MAY 省略其在请求被推送时已经执行过的验证步骤, 前提是它可以验证该请求确实是一个推送请求,并且该请求或 授权服务器策略未以会影响被省略步骤结果的方式被修改。

授权服务器策略 MAY 规定,无论是全局还是 按客户端,PAR 是客户端传递授权请求数据的唯一方式。在 这种情况下,授权服务器会使用 invalid_request 错误代码拒绝 处理任何不带有 request_uri 参数且该参数值不是从 PAR 端点获得的授权端点请求。

5. 授权服务器元数据

引入以下授权服务器元数据参数 [RFC8414],用于传达服务器关于 PAR 的能力和策略。

pushed_authorization_request_endpoint
推送授权请求端点的 URL, 客户端可以在此提交授权请求,以换取可在授权服务器使用的 request_uri 值。
require_pushed_authorization_requests
布尔参数,指示授权 服务器是否只通过 PAR 接受授权请求数据。如果省略,默认值为 false

注意,存在 pushed_authorization_request_endpoint 已足以让客户端确定它可以使用 PAR 流程。从 PAR 端点获得的 request_uri 值可在授权端点使用,而不受其他授权 服务器元数据影响,例如 request_uri_parameter_supportedrequire_request_uri_registration [OIDC.Disco]

6. 客户端元数据

动态客户端注册协议 [RFC7591] 定义了一个 API,用于向授权服务器动态注册 OAuth 2.0 客户端 元数据。[RFC7591] 定义的元数据及其已注册扩展,也蕴含了一个通用的客户端 数据模型,即使未使用动态客户端注册协议,该模型对授权服务器实现也很有用。 这类实现通常会提供某种用户 界面来管理客户端配置。本文档引入以下客户端元数据参数, 用于指示给定客户端是否要求使用推送授权请求。

require_pushed_authorization_requests
布尔参数,指示 客户端允许使用的发起授权请求的唯一方式是否为 PAR。如果省略,默认 值为 false

7. 安全考量

7.1. 请求 URI 猜测

攻击者可能尝试猜测并重放有效的请求 URI 值,并 试图冒充相应客户端。 授权服务器 MUST 考虑 JAR [RFC9101], 第 10.2 节 中关于 request URI 熵的第(d)项考量。

7.2. 开放重定向

攻击者可能试图注册一个指向其控制站点的重定向 URI, 以获取授权码或对用户发起其他攻击。 授权服务器 MUST 只接受来自已认证客户端的 推送授权请求中的新重定向 URI。

7.3. 请求对象重放

攻击者可能重放从合法 授权请求中捕获的请求 URI。为应对此类攻击,授权服务器 SHOULD 使请求 URI 一次性使用。

7.4. 客户端策略变更

在提交 Request Object 与使用特定 Request Object 发起 授权请求之间,客户端策略可能发生变化。因此,建议 授权服务器在处理授权请求时根据客户端策略检查 request 参数。

7.5. 请求 URI 调换

攻击者可能从一个请求中捕获 request URI,然后将其替换到 另一个授权请求中。例如,在 OpenID Connect 语境下,攻击者 可能将请求高认证保证级别的 request URI 替换为 要求较低保证级别的 request URI。客户端 SHOULD 在 推送的 Request Object 中使用 PKCE [RFC7636]、 唯一的 state 参数 [RFC6749], 或 OIDC “nonce”参数 [OIDC], 以防止此攻击。

8. 隐私考量

OAuth 2.0 是一个复杂且灵活的框架,由于其本质上让一个实体在 另外两个实体之间介入用户授权以访问数据,因此具有广泛的隐私影响。 整个 OAuth 的隐私考量超出了本文档范围;本文档 仅定义了在更大框架中发起一个消息序列的替代方式。然而, 使用 PAR 可能会通过降低无意信息披露的可能性来改善隐私, 因为它通过安全连接在 HTTP 请求消息体中直接在客户端和授权服务器之间 传递授权请求数据,而不是在以明文通过用户代理的 URL 查询组件中 传递这些数据。

9. IANA 考量

9.1. OAuth 授权 服务器元数据

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

元数据名称:
pushed_authorization_request_endpoint
元数据描述:
授权服务器推送 授权请求端点的 URL。
变更控制方:
IESG
规范文档:
RFC 9126 的 第 5 节
元数据名称:
require_pushed_authorization_requests
元数据描述:
指示授权服务器 是否只通过 PAR 接受授权请求。
变更控制方:
IESG
规范文档:
RFC 9126 的 第 5 节

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

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

客户端元数据名称:
require_pushed_authorization_requests
客户端元数据描述:
指示客户端是否被要求 使用 PAR 发起授权请求。
变更控制方:
IESG
规范文档:
RFC 9126 的 第 6 节

9.3. OAuth URI 注册

IANA 已在由 [RFC6755] 建立的 [IANA.OAuth.Parameters] 的“OAuth URI”注册表中注册以下值。

URN:
urn:ietf:params:oauth:request_uri:
通用名称:
用于 OAuth Request URI 的 URN 子命名空间。
变更控制方:
IESG
规范文档:
RFC 9126 的 第 2.2 节

10. 参考文献

10.1. 规范性参考文献

[RFC2119]
Bradner, S., “用于 RFC 中表示 要求级别的关键词”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC6749]
Hardt, D., Ed., “OAuth 2.0 授权 框架”, RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC8174]
Leiba, B., “RFC 2119 关键词中大写与 小写的歧义”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259]
Bray, T., Ed., “JavaScript Object Notation (JSON) 数据交换格式”, STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, “OAuth 2.0 授权服务器 元数据”, RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC9101]
Sakimura, N., Bradley, J., and M. Jones, “OAuth 2.0 授权 框架:JWT 安全授权请求(JAR)”, RFC 9101, DOI 10.17487/RFC9101, , <https://www.rfc-editor.org/info/rfc9101>.

10.2. 资料性参考文献

[IANA.OAuth.Parameters]
IANA, “OAuth 参数”, <http://www.iana.org/assignments/oauth-parameters>.
[OAUTH-SECURITY-TOPICS]
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, “OAuth 2.0 安全当前最佳实践”, 进行中的工作, Internet-Draft, draft-ietf-oauth-security-topics-18, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-18>.
[OAUTH-V2]
Hardt, D., Parecki, A., and T. Lodderstedt, “OAuth 2.1 授权 框架”, 进行中的工作, Internet-Draft, draft-ietf-oauth-v2-1-03, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-03>.
[OIDC]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, “OpenID Connect Core 1.0 incorporating errata set 1”, , <http://openid.net/specs/openid-connect-core-1_0.html>.
[OIDC.Disco]
Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0 incorporating errata set 1”, , <http://openid.net/specs/openid-connect-discovery-1_0.html>.
[RFC6755]
Campbell, B. and H. Tschofenig, “用于 OAuth 的 IETF URN 子命名空间”, RFC 6755, DOI 10.17487/RFC6755, , <https://www.rfc-editor.org/info/rfc6755>.
[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>.
[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>.
[RFC8252]
Denniss, W. and J. Bradley, “用于原生应用的 OAuth 2.0”, BCP 212, RFC 8252, DOI 10.17487/RFC8252, , <https://www.rfc-editor.org/info/rfc8252>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, “OAuth 2.0 Mutual-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 的 Resource Indicators”, RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.

致谢

本规范基于 OpenID Foundation 的 Financial-grade API Working Group 开展的 Pushed Request Object 工作。我们感谢该工作组成员的宝贵贡献。

我们感谢 Vladimir DzhuvinovAaron PareckiJustin RicherSascha PreibischDaniel FettMichael B. JonesAnnabelle BackmanJoseph HeenanSean GlencrossMaggie HungNeil MaddenKarsten Meyer zu SelhausenRoman DanyliwMeral ShirazipourTakahiko Kawasaki 对本文档提出的宝贵反馈。

作者地址

Torsten Lodderstedt
yes.com
Brian Campbell
Ping Identity
Nat Sakimura
NAT.Consulting
Dave Tonge
Moneyhub Financial Technology
Filip Skokan
Auth0