RFC 9101 OAuth JAR 2021年8月
Sakimura, et al. 标准跟踪 [页]
流:
互联网工程任务组(IETF)
RFC:
9101
类别:
标准跟踪
发布:
ISSN:
2070-1721
作者:
N. Sakimura
NAT.Consulting
J. Bradley
Yubico
M. Jones
Microsoft

RFC 9101

OAuth 2.0 授权框架:JWT 保护的授权请求(JAR)

摘要

RFC 6749 中描述的 OAuth 2.0 授权请求使用 查询参数序列化,这意味着授权请求 参数被编码在请求的 URI 中,并通过诸如 Web 浏览器 之类的用户代理发送。虽然这易于实现,但这意味着 a) 通过用户代理进行的通信未受完整性 保护,因此参数可能被污染,b) 通信来源未经过身份验证,并且 c) 通过用户代理进行的通信 可能被监视。由于这些弱点, 现在已经提出了针对该协议的若干攻击。

本文档引入了改为在 JSON Web Token (JWT) 中发送请求参数的能力,这允许使用 JSON Web Signature (JWS) 对请求进行签名,并使用 JSON Web Encryption (JWE) 对其加密,从而获得授权请求的完整性、 来源身份验证和机密性 属性。请求可以按值发送,也可以按引用发送。

本备忘录的状态

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

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

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

目录

1. 引言

OAuth 2.0 [RFC6749] 中的授权请求 使用查询参数 序列化,并且通常通过诸如 Web 浏览器之类的用户代理发送。

例如,参数 response_typeclient_idstateredirect_uri 被编码在请求的 URI 中:

    GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com

虽然这易于实现,但 URI 中的编码 不允许使用应用层安全性来 提供机密性和完整性保护。 虽然 TLS 用于在客户端和用户代理之间以及用户代理和 授权服务器之间提供通信安全性,但 TLS 会话在用户代理处终止。 此外,TLS 会话可能在某些中间盒 (例如负载均衡器)处过早终止。

因此,[RFC6749] 的授权请求 存在以下缺陷:

(a)
通过用户代理进行的通信 没有完整性保护,因此参数可能被篡改 (完整性保护失败);
(b)
通信来源未经过身份验证 (来源身份验证失败);
(c)
通过用户代理进行的通信可能被监视 (遏制/机密性失败)。

由于这些固有弱点,已经发现了若干针对该 协议的攻击,例如重定向 URI 重写。

使用应用层安全性可以缓解这些问题。

使用应用层安全性允许请求由 受信任的第三方准备,从而客户端应用程序不能请求 超出先前约定范围的权限。

此外,通过引用传递请求可以减少线上传输开销。

之所以选择 JWT [RFC7519] 编码,是因为:

(1)
它与 JSON 关系密切, JSON 被用作 OAuth 的响应格式
(2)
由于其文本性质,它对开发者友好
(3)
与 XML 相比,它相对紧凑
(4)
它以及相关的签名和加密方法 [RFC7515] [RFC7516] 的开发状态为 Proposed Standard
(5)
与 XML Signature 和 Encryption 相比,JWS 和 JWE 相对易用。

参数 requestrequest_uri 被作为 OAuth 2.0 [RFC6749] 流程的附加授权请求参数引入。 request 参数 是一个 JSON Web Token (JWT) [RFC7519],其 JWT Claims Set 保存 JSON 编码的 OAuth 2.0 授权请求参数。 注意,与 RFC 7519 不同,Claims Set 的元素是 已编码的 OAuth 请求参数 [IANA.OAuth.Parameters], 仅补充少量由 IANA 管理的 JSON Web Token Claims [IANA.JWT.Claims],特别是 issaudrequest 参数中的 JWT 使用 JWS 进行完整性 保护和来源身份验证。

JWT [RFC7519] 可以 通过引用传递给授权端点, 在这种情况下,使用参数 request_uri 而不是 request

使用 JWT [RFC7519] 作为请求编码而不是查询 参数有若干优点:

(a)
完整性保护。 可以对请求进行签名,以便检查请求的完整性。
(b)
来源身份验证。 可以对请求进行签名,以便对签名者进行身份验证。
(c)
机密性保护。 可以对请求进行加密,从而即使 TLS 连接在 某处终止(包括在用户代理处以及之前),也能提供 端到端机密性。
(d)
收集最小化。请求可以由受信任的 第三方签名,以证明该授权请求符合 某项策略。例如,请求可以由 受信任的第三方预先审查,以确认所请求的所有个人数据 对执行最终用户所请求的流程是 严格必要的;然后,该请求将由该受信任的第三方签名。 随后,授权服务器检查签名,并向 最终用户显示合规状态,使最终用户在授权时 对请求的合法性具有一定保证。在某些情况下,在这种 情况下甚至可能希望跳过授权对话。

有少数情况下,通过引用请求很有用,例如:

  1. 当希望减少所传输请求的大小时。 使用应用层安全性会增加 请求大小,尤其是在使用公钥密码学时。
  2. 当客户端不想执行应用级 密码运算时。授权服务器可以提供一个端点, 通过与客户端直接通信来接受授权请求, 这样客户端经过身份验证,并且信道受 TLS 保护。

OpenID Connect [OpenID.Core] 正在使用此能力。

1.1. 需求语言

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

2. 术语

就本规范而言,除了 OAuth 2.0 Framework [RFC6749]JSON Web Signature [RFC7515]JSON Web Encryption [RFC7516] 中定义的内容之外,还适用以下术语和 定义。

2.1. 请求对象

请求对象是一个 JSON Web Token (JWT) [RFC7519],其 JWT Claims Set 保存 JSON 编码的 OAuth 2.0 授权请求 参数。

2.2. 请求对象 URI

请求对象 URI 是一个绝对 URI,它引用组成 OAuth 2.0 授权请求的一组参数。该 URI 引用的资源的内容 是一个 请求 对象第 2.1 节,除非该 URI 是由同一授权服务器提供给客户端的,在这种情况下, 其内容是由授权服务器自行决定的实现细节。内容为请求对象是为了确保在 request_uri 的提供者与使用者是不同 实体时的互操作性,例如客户端提供一个 URI, 该 URI 引用存储在客户端后端服务上的请求对象, 并可通过 HTTPS 访问。在后一种情况下,授权服务器 既是该 URI 的提供者又是使用者,例如它提供一个端点, 以请求对象换取 URI 时,这种互操作性顾虑并不适用。

3. 符号和缩略术语

以下缩略语为本规范通用。

JSON:
JavaScript 对象表示法
JWT:
JSON Web Token
JWS:
JSON Web Signature
JWE:
JSON Web Encryption
URI:
统一资源标识符
URL:
统一资源定位符

4. 请求对象

请求对象第 2.1 节 用于 为 OAuth 2.0 授权 请求提供授权请求参数。它 MUST 包含用于处理 OAuth 2.0 [RFC6749] 授权请求的所有参数(包括扩展 参数),但本文档中定义的 requestrequest_uri 参数除外。 这些参数表示为该对象的 JWT Claims。 参数名和字符串值 MUST 作为 JSON 字符串包含。 由于请求对象跨域处理,并且可能 位于封闭生态系统之外,根据 [RFC8259] 第 8.1 节, 这些 JSON 字符串 MUST 使用 UTF-8 [RFC3629] 编码。 数值 MUST 作为 JSON 数字包含。 请求对象 MAY 包含任何扩展参数。 此 JSON [RFC8259] 对象构成 JWT [RFC7519] 中定义的 JWT Claims Set。 随后 JWT Claims Set 会被签名,或被签名并加密。

签名时,使用 JSON Web Signature (JWS) [RFC7515]。 结果是一个 JWS 签名的 JWT [RFC7519]。如果 被签名,授权请求对象 SHOULD 包含 Claims iss(issuer)和 aud(audience)作为成员, 其语义与 JWT [RFC7519] 规范中定义的相同。aud 的值 应为授权服务器(AS)的 issuer 值,如 RFC 8414 [RFC8414] 中所定义。

加密时,使用 JWE [RFC7516]。 当同时应用签名和加密时, JWT MUST 先签名,再加密,如 [RFC7519] 第 11.2 节 所述。 结果是 [RFC7519] 中定义的嵌套 JWT。

客户端确定用于签名和加密 请求对象的算法。所选算法需要由 客户端和授权服务器共同支持。客户端可以 在其动态客户端注册元数据 [RFC7591] 中告知 授权服务器它所支持的算法, 具体而言,是元数据值 request_object_signing_algrequest_object_encryption_algrequest_object_encryption_enc。同样, 授权服务器可以在其授权服务器元数据 [RFC8414] 中告知客户端它所支持的算法, 具体而言,是元数据值 request_object_signing_alg_values_supportedrequest_object_encryption_alg_values_supportedrequest_object_encryption_enc_values_supported

请求对象 MAY 按值发送,如 第 5.1 节 所述, 或按引用发送,如 第 5.2 节 所述。 requestrequest_uri 参数 MUST NOT 包含在请求对象中。

请求对象第 2.1 节 具有媒体 类型 [RFC2046] application/oauth-authz-req+jwt。注意,某些现有 部署可能也在使用类型 application/jwt

以下是在 base64url [RFC7515] 编码 和签名之前,请求对象中 Claims 的示例。 注意,它包含扩展参数 noncemax_age

  {
   "iss": "s6BhdRkqt3",
   "aud": "https://server.example.com",
   "response_type": "code id_token",
   "client_id": "s6BhdRkqt3",
   "redirect_uri": "https://client.example.org/cb",
   "scope": "openid",
   "state": "af0ifjsldkj",
   "nonce": "n-0S6_WzA2Mj",
   "max_age": 86400
  }

使用 RS256 算法 [RFC7518] 对其签名 将产生以下请求对象值 (值中的换行仅用于显示目的):

  eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6ICJzNkJoZF
  JrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLAog
  ICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2xpZW50X2
  lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHRwczovL2Ns
  aWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3BlbmlkIiwKICAgIC
  JzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2UiOiAibi0wUzZfV3pBMk1q
  IiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW_ToI1yrEJ67BgK
  b5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5YVY-vnW0_PLJb1C2
  HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKzuKzqSb1wAZALo5f89B_p6QA6j6
  JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3EYLYaCb4ik4I1zGXE4fvim9FIMs8O
  CMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W9typPf846lGwA8h9G9oNTIuX8Ft2jf
  pnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3j1i7tLR_5Nz-g

以下 RSA 公钥以 JSON Web Key (JWK) 格式表示,可用于验证本示例和后续请求对象示例中的 请求对象签名(值中的换行 仅用于显示目的):

  {
   "kty":"RSA",
   "kid":"k2bdc",
   "n":"x5RbkAZkmpRxia65qRQ1wwSMSxQUnS7gcpVTV_cdHmfmG2ltd2yabEO9XadD8
        pJNZubINPpmgHh3J1aD9WRwS05ucmFq3CfFsluLt13_7oX5yDRSKX7poXmT_5
        ko8k4NJZPMAO8fPToDTH7kHYbONSE2FYa5GZ60CUsFhSonI-dcMDJ0Ary9lxI
        w5k2z4TAdARVWcS7sD07VhlMMshrwsPHBQgTatlkxyIHXbYdtak8fqvNAwr7O
        lVEvM_Ipf5OfmdB8Sd-wjzaBsyP4VhJKoi_qdgSzpC694XZeYPq45Sw-q51iF
        UlcOlTCI7z6jltUtnR6ySn6XDGFnzH5Fe5ypw",
   "e":"AQAB"
  }

5. 授权请求

客户端通过使用 application/x-www-form-urlencoded 格式将以下参数添加到授权端点 URI 的查询组件中, 来构造授权请求 URI:

request
REQUIRED,除非指定了 request_uri。 保存 [RFC6749] 第 4 节(OAuth 2.0)中所述授权请求参数的 请求对象第 2.1 节。 如果此参数存在于授权请求中, 则 request_uri MUST NOT 存在。
request_uri
REQUIRED,除非指定了 request。 按 RFC 3986 [RFC3986] 定义的绝对 URI,即引用 [RFC6749] 第 4 节(OAuth 2.0)中所述授权请求 参数的 请求对象 URI第 2.2 节。 如果此参数存在于授权请求中, 则 request MUST NOT 存在。
client_id
REQUIREDOAuth 2.0 [RFC6749] client_id。该值 MUSTrequestrequest_uri 请求对象的第 2.1 节 client_id 匹配。

客户端使用 HTTP 重定向响应,或通过用户代理可用的其他方式, 将资源所有者引导到所构造的 URI。

例如,客户端引导最终用户的用户代理发出 以下 HTTPS 请求:

GET /authz?client_id=s6BhdRkqt3&request=eyJhbG..AlMGzw HTTP/1.1
Host: server.example.com

为简洁起见,request 参数的值已缩写。

授权请求对象 MUST 为以下之一:

(a)
JWS 签名
(b)
JWS 签名并 JWE 加密

客户端 MAY 同时在查询参数中 发送请求对象中所包含参数的重复副本, 以便向后兼容等。 但是,支持本规范的授权服务器 MUST 只使用请求对象中包含的参数。

5.1. 按值传递请求对象

客户端将授权请求作为 请求对象发送到授权端点,作为 request 参数值。

以下是使用 request 参数的 授权请求示例 (值中的换行仅用于显示目的):

  https://server.example.com/authorize?client_id=s6BhdRkqt3&
    request=eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6
    ICJzNkJoZFJrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBs
    ZS5jb20iLAogICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAg
    ICAiY2xpZW50X2lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6
    ICJodHRwczovL2NsaWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAi
    b3BlbmlkIiwKICAgICJzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2Ui
    OiAibi0wUzZfV3pBMk1qIiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VU
    ElVaPjqW_ToI1yrEJ67BgKb5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC
    0iQJwXu5YVY-vnW0_PLJb1C2HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKz
    uKzqSb1wAZALo5f89B_p6QA6j6JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3E
    YLYaCb4ik4I1zGXE4fvim9FIMs8OCMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W
    9typPf846lGwA8h9G9oNTIuX8Ft2jfpnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3
    j1i7tLR_5Nz-g

5.2. 按引用传递请求对象

request_uri 授权请求参数使得 OAuth 授权请求能够按引用而不是 按值传递。此参数的使用方式与 request 参数相同,只是请求对象值 从指定 URI 所标识的资源中取得, 而不是按值传递。

整个请求 URI SHOULD NOT 超过 512 个 ASCII 字符。 这一限制有两个原因:

  1. 在撰写本文时,市场上的许多手机仍不接受 大型载荷。该限制通常为 512 或 1024 个 ASCII 字符。
  2. 在 2G 移动连接这类慢速连接上,大型 URL 会导致响应缓慢;因此,从用户体验角度看, 不建议使用这种方式。

request_uri 引用的资源内容 MUST 是请求对象,并且 MUST 可由授权服务器访问, 除非该 URI 是由授权服务器提供给客户端的。 在第一种情况下,request_uri MUSThttps URI, 如 [RFC7230] 第 2.7.2 节 所规定。 在第二种情况下,它 MUST 是 URN, 如 [RFC8141] 所规定。

以下是 可由 request_uri 引用的 请求对象资源内容示例 (值中的换行仅用于显示目的):

  eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6ICJzNkJoZF
  JrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLAog
  ICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2xpZW50X2
  lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHRwczovL2Ns
  aWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3BlbmlkIiwKICAgIC
  JzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2UiOiAibi0wUzZfV3pBMk1q
  IiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW_ToI1yrEJ67BgK
  b5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5YVY-vnW0_PLJb1C2
  HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKzuKzqSb1wAZALo5f89B_p6QA6j6
  JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3EYLYaCb4ik4I1zGXE4fvim9FIMs8O
  CMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W9typPf846lGwA8h9G9oNTIuX8Ft2jf
  pnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3j1i7tLR_5Nz-g

5.2.1. 引用请求对象的 URI

客户端将请求对象资源存储在本地或远程某个 授权服务器可以访问的 URI 处。 这样的设施可以由授权服务器 或受信任的第三方提供。例如,授权服务器可以 提供一个 URL,客户端向其 POST 请求对象并 获得请求 URI。 此 URI 即请求对象 URI,request_uri

请求对象可能包含只应 向授权服务器披露的值。 因此,request_uri MUST 在其生命周期内 具有适当熵, 以便在可公开检索时该 URI 不可猜测。 有关指导,请参见 [RFC6819] 第 5.1.4.2.2 节 和 "Capability URL 的良好实践" [CapURLs]RECOMMENDED 在合理超时后移除 request_uri, 除非采取了访问控制措施。

以下是 请求对象 URI 值的示例 (值中的换行仅用于显示目的)。 在此示例中,受信任的第三方服务托管该请求对象。

  https://tfp.example.org/request.jwt/
    GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM

5.2.2. 使用 "request_uri" 请求参数的请求

客户端将授权请求发送到 授权端点。

以下是 使用 request_uri 参数的授权请求示例 (值中的换行仅用于显示目的):

  https://server.example.com/authorize?
    client_id=s6BhdRkqt3
    &request_uri=https%3A%2F%2Ftfp.example.org%2Frequest.jwt
    %2FGkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM

5.2.3. 授权服务器获取请求对象

收到请求后,授权服务器 MUSTrequest_uri 发送 HTTP GET 请求,以检索被引用的请求对象, 除非该请求对象以某种方式存储,使服务器能够 通过其他机制安全地检索它并解析它,以 重新创建授权请求参数。

以下是此获取 过程的示例。在此示例中,受信任的第三方服务托管 请求对象。

GET /request.jwt/GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM HTTP/1.1
Host: tfp.example.org

以下是获取 响应的示例:

  HTTP/1.1 200 OK
  Date: Thu, 20 Aug 2020 23:52:39 GMT
  Server: Apache/2.4.43 (tfp.example.org)
  Content-type: application/oauth-authz-req+jwt
  Content-Length: 797
  Last-Modified: Wed, 19 Aug 2020 23:52:32 GMT

  eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6ICJzNkJoZF
  JrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLAog
  ICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2xpZW50X2
  lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHRwczovL2Ns
  aWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3BlbmlkIiwKICAgIC
  JzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2UiOiAibi0wUzZfV3pBMk1q
  IiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW_ToI1yrEJ67BgK
  b5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5YVY-vnW0_PLJb1C2
  HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKzuKzqSb1wAZALo5f89B_p6QA6j6
  JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3EYLYaCb4ik4I1zGXE4fvim9FIMs8O
  CMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W9typPf846lGwA8h9G9oNTIuX8Ft2jf
  pnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3j1i7tLR_5Nz-g

6. 验证基于 JWT 的请求

6.1. JWE 加密的请求 对象

如果请求对象已加密, 授权服务器 MUST 按照 JSON Web Encryption [RFC7516] 规范解密 JWT。

结果是一个已签名的请求对象。

如果解密失败,授权服务器 MUST 在响应授权请求时向客户端返回 invalid_request_object 错误。

6.2. JWS 签名的请求 对象

授权服务器 MUST 验证 JWS 签名的 [RFC7515] 请求 对象的签名。如果存在 kid Header Parameter,则所标识的密钥 MUST 是所使用的密钥,并且 MUST 是 与客户端关联的密钥。签名 MUST 使用与客户端关联的密钥以及 alg Header Parameter 中指定的算法进行验证。算法验证 MUST 按照 [RFC8725]3.1 节和第 3.2 节中的规定执行。

如果密钥未与客户端关联,或者签名 验证失败,授权服务器 MUST 在响应授权请求时向客户端返回 invalid_request_object 错误。

6.3. 请求参数 组装与验证

授权服务器 MUST 从请求对象值中 提取授权请求参数集。 授权服务器 MUST 只使用 请求对象中的参数,即使同一 参数也在查询参数中提供。 client_id 请求参数中的客户端 ID 值 和请求对象 client_id claim 中的客户端 ID 值 MUST 相同。 然后,授权服务器按照 OAuth 2.0 [RFC6749] 中的规定验证该请求。

如果客户端 ID 检查或请求验证失败,则 授权服务器 MUST 按照 [RFC6749] 第 5.2 节(OAuth 2.0)中的规定, 在响应授权请求时向客户端返回错误。

7. 授权服务器响应

授权服务器响应按照 [RFC6749] 第 4 节(OAuth 2.0)中的方式创建并发送给客户端。

此外,本文档使用这些附加错误值:

invalid_request_uri
授权请求中的 request_uri 返回错误或包含无效数据。
invalid_request_object
request 参数包含 无效的请求对象。
request_not_supported
授权服务器不支持 使用 request 参数。
request_uri_not_supported
授权服务器不支持使用 request_uri 参数。

8. TLS 要求

支持请求对象 URI 方法的客户端实现 MUST 支持 TLS,并遵循 "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)" [RFC7525]

为了防止信息披露和篡改, MUST 使用具有 机密性和完整性保护的密码套件的 TLS 来应用机密性保护。

HTTP 客户端 MUST 还使用 DNS-ID [RFC6125] 验证 TLS 服务器证书,以避免中间人攻击。 此处适用 [RFC6125] 中定义的规则和指南,并包含以下 考虑事项:

9. IANA 考虑事项

9.1. OAuth 参数 注册

由于请求对象是 JWT,核心 JWT claims 不能 在请求对象中用于 JWT 所规定内容之外的任何目的。 因此,它们已被注册为 OAuth 授权请求参数,以避免未来的 OAuth 扩展 以不同含义使用它们。

本规范向 [RFC6749] 建立的 "OAuth Parameters" 注册表 [IANA.OAuth.Parameters] 添加以下值。

名称:
iss
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.1 节
名称:
sub
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.2 节
名称:
aud
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.3 节
名称:
exp
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.4 节
名称:
nbf
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.5 节
名称:
iat
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.6 节
名称:
jti
参数使用位置:
授权请求
变更控制者:
IETF
规范文档:
本文档和 [RFC7519] 第 4.1.7 节

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

本规范向 [RFC8414] 建立的 "OAuth Authorization Server Metadata" 注册表 [IANA.OAuth.Parameters] 添加以下值。

元数据名称:
require_signed_request_object
元数据描述:
指示授权 请求何处需要作为请求对象受到保护,并通过 requestrequest_uri parameter 提供。
变更控制者:
IETF
规范文档:
本文档的第 10.5 节

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

本规范向 [RFC7591] 建立的 "OAuth Dynamic Client Registration Metadata" 注册表 [IANA.OAuth.Parameters] 添加以下值。

元数据名称:
require_signed_request_object
元数据描述:
指示授权 请求何处需要作为请求对象受到保护,并通过 requestrequest_uri parameter 提供。
变更控制者:
IETF
规范文档:
本文档的第 10.5 节

9.4. 媒体类型 注册

9.4.1. 注册表内容

本节按照 [RFC6838] 中描述的方式, 在 "Media Types" 注册表 [IANA.MediaTypes] 中 注册 application/oauth-authz-req+jwt 媒体类型 [RFC2046]。它可用于 指示内容是包含请求 对象 claims 的 JWT。

类型名称:
application
子类型名称:
oauth-authz-req+jwt
必需参数:
N/A
可选参数:
N/A
编码考虑事项:
binary; 请求对象是 JWT; JWT 值被编码为一系列 base64url 编码的值(其中一些可能是 空字符串),并由句点(.)字符分隔。
安全考虑事项:
参见 RFC 9101 的 第 10 节
互操作性考虑事项:
N/A
已发布的规范:
RFC 9101 的第 4 节
使用此媒体类型的应用:
使用请求对象来发出 OAuth 2.0 授权 请求的应用
片段标识符考虑事项:
N/A
附加信息:


此类型的已废弃别名:
N/A
魔数:
N/A
文件扩展名:
N/A
Macintosh 文件类型代码:
N/A
联系人及电子邮件地址:

Nat Sakimura <nat@nat.consulting>
预期用途:
COMMON
使用限制:
作者:
Nat Sakimura <nat@nat.consulting>
变更控制者:
IETF
临时注册?

10. 安全考虑事项

除了 OAuth 2.0 中讨论的所有安全 考虑事项 [RFC6819] 之外, 还需要考虑 [RFC7515][RFC7516][RFC7518][RFC8725] 中的安全 考虑事项。此外,还有若干学术论文,例如 [BASIN],它们为 OAuth 之类协议的安全 属性提供了有用见解。

考虑到上述内容,本文档建议将 以下安全考虑事项纳入考虑。

10.1. 算法选择

通过 request 参数发送授权请求对象时,它 MUST 使用 JWS [RFC7515] 签名,或者分别使用 JWS [RFC7515]JWE [RFC7516] 先签名后加密, 并使用当时认为适当的算法。

10.2. 请求来源 身份验证

授权请求的来源 MUST 始终被 验证。有几种方法可以做到这一点:

(a)
验证请求对象的 JWS 签名。
(b)
如果 JWE 使用对称加密,则验证用于 JWE 加密的对称密钥是 正确的密钥。但请注意, 如果使用公钥加密,则加密不会启用来源身份验证, 因为任何一方都可以加密到公钥。
(c)
验证请求对象 URI 的 TLS 服务器身份。 在这种情况下,授权服务器 MUST 通过 带外方式知道客户端使用该请求对象 URI,并且 TLS 证书只覆盖该客户端。 一般而言,这不是一种可靠的方法。
(d)
当授权服务器实现一项服务, 以请求对象换取并返回请求对象 URI 时, 授权 服务器 MUST 执行客户端身份验证,以接受 请求对象,并将客户端标识符 绑定到它所提供的请求对象 URI。 它 MUST 按照 (a) 验证签名。 由于请求对象 URI 可以被重放,请求对象 URI 的生命周期 MUST 很短,并且最好 一次性使用。请求对象 URI 的熵 MUST 足够大。 有效期的适当短度和 请求对象 URI 的熵取决于基于受保护 资源价值的风险计算。对有效时间的一般指导 是少于一分钟, 并且在撰写本规范时,请求对象 URI 应包含 128 位或更多的密码学 随机值。
(e)
当受信任的第三方服务以请求对象换取并返回请求对象 URI 时, 它 MUST 按照 (a) 验证 签名。此外,授权服务器 MUST 被该第三方服务信任,并且 MUST 通过带外方式知道客户端也受其信任。

10.3. 显式端点

尽管本规范并不要求它们, 但诸如 [BASIN] 之类的研究指出, 一项良好实践是以防篡改的 方式显式说明预期的交互端点和 消息在序列中的位置,从而使发起者的意图明确无歧义。本 规范 RECOMMENDED 将此 实践用于 [RFC6749][RFC6750][RFC8414] 中定义的以下端点:

(a)
受保护资源(protected_resources
(b)
授权端点(authorization_endpoint
(c)
重定向 URI(redirect_uri
(d)
令牌端点(token_endpoint

此外,如果使用动态发现,则此实践也适用于 发现相关端点。

[RFC6749] 中, 虽然重定向 URI 包含在授权请求中,但其他端点 不包含。因此,同样的情况也适用于授权 请求对象。

10.4. 与 request_uri 相关的风险

引入 request_uri 会带来若干攻击可能性。 有关与 URI 相关 风险的更多信息,请查阅 [RFC3986] 第 7 节

10.4.1. 针对 授权服务器的 DDoS 攻击

一组恶意客户端可以通过将 request_uri 指向一个 返回极大内容或响应极慢的 URI, 对授权服务器发起 DoS 攻击。 在这种攻击下,服务器可能耗尽其资源 并开始失败。

类似地,恶意客户端可以指定一个 request_uri 值, 该值本身指向一个使用 request_uri 的授权请求 URI, 从而导致递归查找。

为防止此类攻击成功,服务器应当 a) 检查 request_uri 参数的值未指向意外位置, b) 检查响应的媒体类型是 application/oauth-authz-req+jwt, c) 对获取 request_uri 内容实现超时,并且 d) 不对 request_uri 执行递归 GET。

10.4.2. 请求 URI 重写

request_uri 的值未被签名; 因此,它可能被浏览器中的中间人攻击者篡改。 因此会出现若干攻击可能性。例如, a) 攻击者可以创建重写后的 URI 指向的另一个文件,从而使请求额外 scope 成为可能,或者 b) 攻击者可以通过将 request_uri 的值设置为受害者的值, 对受害者站点发起 DoS 攻击。

为防止此类攻击成功,服务器应当 a) 检查 request_uri 参数的值未指向意外位置, b) 检查响应的媒体类型是 application/oauth-authz-req+jwt,并且 c) 对获取 request_uri 的内容实现超时。

10.5. 降级攻击

除非客户端和服务器使用的协议被锁定为 使用 OAuth JWT 保护的授权请求(JAR),否则 攻击者可能使用 RFC 6749 请求 绕过本规范提供的所有保护。

为防止这种攻击,本规范定义了新的 客户端元数据和服务器元数据值,二者均命名为 require_signed_request_object,其值均为 布尔值。

当其作为客户端元数据的值为 true 时, 服务器 MUST 拒绝来自 客户端且不符合本规范的授权请求。如果请求对象 在此服务器元数据值为 true 时使用 algnone,它 MUST 也拒绝该请求。如果省略,则默认值为 false

当其作为服务器元数据的值为 true 时, 服务器 MUST 拒绝来自 任何不符合本规范的客户端的授权请求。如果请求对象 使用 algnone,它 MUST 也拒绝该请求。如果省略, 默认值为 false

注意,即使不存在 require_signed_request_object 元数据 值,客户端 MAY 也可以使用已签名的请求对象, 前提是客户端和服务器共同支持签名算法。 签名算法元数据的使用在第 4 节中描述。

10.7. 参数不匹配

鉴于 OAuth 参数值会在两个不同位置发送, 即作为普通 OAuth 参数和作为请求对象 claims, 实现必须防范可能使用不匹配 参数值来获得非预期结果的攻击。 这就是两个客户端 ID 值 MUST 匹配的原因, 也是只使用请求对象中的参数值的原因, 以及 requestrequest_uri 都不能出现在请求对象中的原因。

10.8. 跨 JWT 混淆

[RFC8725] 第 2.8 节 所述, 攻击者可能试图在某个 JWT 并非为其设计的上下文中使用该 JWT。 针对这些攻击描述的缓解措施可以应用于请求对象。

攻击者可能试图重新利用请求对象的一种方式, 是尝试将其用作客户端身份验证 JWT, 如 [RFC7523] 第 2.2 节 所述。 防止这种情况的一种简单方式是永远不要在请求对象中 将客户端 ID 用作 sub 值。

防止跨 JWT 混淆的另一种方式是使用显式类型, 如 [RFC8725] 第 3.11 节 所述。 可以通过包含值为 oauth-authz-req+jwttyp Header Parameter, 来显式地为请求对象指定类型 (该值已在第 9.4.1 节中注册)。 但请注意,在现有授权服务器上要求显式类型化请求对象 会破坏大多数现有部署, 因为现有客户端已经普遍使用无类型请求对象, 特别是在 OpenID Connect [OpenID.Core] 中。 但是,对于无需考虑与现有部署兼容性的 新 OAuth 部署配置文件,要求显式类型化会是一个好主意。

最后,防止跨 JWT 混淆的另一种方式是使用一种密钥 管理机制,其中用于签名请求对象的密钥 可以明确区别于用于其他目的的密钥。这样,如果 对手试图在另一上下文中重新利用请求对象,就会发生密钥 不匹配,从而挫败攻击。

11. 隐私考虑事项

当客户端被授予访问包含个人数据的受保护资源的权限时, 客户端 和授权服务器都需要遵守 隐私原则。 "Privacy Considerations for Internet Protocols" [RFC6973] 为协议设计和实现的 改进提供了极佳指导。 应当遵循其中列出的规定。

大多数规定都适用于 "The OAuth 2.0 Authorization Framework" [RFC6749] 和 "The OAuth 2.0 Authorization Framework: Bearer Token Usage" [RFC6750], 并非本规范所特有。 下文仅指出 本规范特有的规定。

11.1. 收集限制

当客户端被授予访问包含个人数据的受保护资源的权限时, 客户端 SHOULD 将 个人数据收集限制在适用法律范围内,并且严格限于指定目的所必要的内容。

用户通常很难确定所请求的个人数据 是否严格必要。受信任的第三方服务可以通过 审查客户端请求、将其与客户端拟议的 处理进行比较,并对该请求进行认证,从而帮助 用户。认证后,客户端在发出授权请求时,可以 向受信任的第三方服务提交授权请求,以 获得请求对象 URI。此过程包含两个步骤:

(1)
(认证过程)受信任的第三方服务审查 客户端的业务流程,并确定其需要哪些 claims; 这就是认证过程。客户端一旦 通过认证,就会获得客户端凭据,用于进行身份验证, 以便将请求对象推送到受信任的第三方服务 来获取 request_uri
(2)
(转换过程)客户端使用它获得的客户端凭据, 将请求对象推送到受信任的第三方服务 以获取 request_uri。受信任的第三方服务 还会验证请求对象与客户端根据前一步 有资格获得的 claims 保持一致。

在授权请求中收到这样的请求对象 URI 后, 授权服务器首先验证 请求对象 URI 的 authority 部分是否为受信任第三方 服务的合法 authority。然后,授权服务器向 请求对象 URI 发出 HTTP GET 请求。连接时,授权服务器 MUST 验证 TLS 证书中表示的服务器身份 对该请求对象 URI 是合法的。随后, 授权服务器可以获得请求对象,其中包括代表客户端的 client_id

同意屏幕 MUST 指示客户端,并且 SHOULD 指示该请求已由 受信任的第三方服务审查,符合收集 限制原则。

11.2. 披露限制

11.2.1. 请求披露

本规范允许扩展参数。 这些参数可能包含潜在敏感信息。 由于 URI 查询参数可能通过各种 方式泄露,最显著的是通过 referrer 和浏览器历史记录泄露, 因此,如果授权请求包含潜在敏感 参数,客户端 SHOULD 使用 JWE [RFC7516] 加密 请求对象。

在使用请求对象 URI 方法的情况下,如果请求 对象包含个人身份信息或敏感信息, request_uri SHOULD 仅使用一次 并具有较短有效期,并且它 MUST 具有 适用于相关安全策略的足够熵,除非 请求对象本身使用 JWE [RFC7516] 加密。请求对象 URI 的 有效期的适当短度和熵取决于 基于受保护资源价值的风险 计算。对有效时间的一般指导是少于 一分钟,并且在撰写本规范时,请求对象 URI 应包含 128 位或更多的密码学随机值。

11.2.2. 使用 请求对象 URI 进行跟踪

即使受保护资源不包含 个人身份信息, 如果使用持久的静态按用户 请求对象 URI,有时也可能通过请求对象 URI 识别用户。 第三方可能通过浏览器历史记录等观察到 它,并开始使用它关联 用户的活动。 在某种意义上,这也是一种数据披露, 应当避免。

因此,应避免使用按用户持久的请求对象 URI。 一次性请求对象 URI 是一种替代方案。

12. 参考文献

12.1. 规范性参考文献

[RFC2119]
Bradner, S., "RFC 中用于 表示要求级别的关键词", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3629]
Yergeau, F., "UTF-8,ISO 10646 的转换格式", STD 63, RFC 3629, DOI 10.17487/RFC3629, , <https://www.rfc-editor.org/info/rfc3629>.
[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>.
[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>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., "超文本传输协议 (HTTP/1.1):消息语法和路由", RFC 7230, DOI 10.17487/RFC7230, , <https://www.rfc-editor.org/info/rfc7230>.
[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>.
[RFC7516]
Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)", RFC 7516, DOI 10.17487/RFC7516, , <https://www.rfc-editor.org/info/rfc7516>.
[RFC7518]
Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, DOI 10.17487/RFC7518, , <https://www.rfc-editor.org/info/rfc7518>.
[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>.
[RFC7525]
Sheffer, Y., Holz, R., and P. Saint-Andre, "传输层安全性 (TLS) 和数据报传输层安全性 (DTLS) 安全使用建议", BCP 195, RFC 7525, DOI 10.17487/RFC7525, , <https://www.rfc-editor.org/info/rfc7525>.
[RFC8141]
Saint-Andre, P. and J. Klensin, "统一资源名称 (URN)", RFC 8141, DOI 10.17487/RFC8141, , <https://www.rfc-editor.org/info/rfc8141>.
[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>.

12.2. 资料性参考文献

[BASIN]
Basin, D., Cremers, C., and S. Meier, "可证明地修复用于实体认证的 ISO/IEC 9798 标准", Journal of Computer Security - Security and Trust Principles, Volume 21, Issue 6, pp. 817-846, , <https://www.cs.ox.ac.uk/people/cas.cremers/downloads/papers/BCM2012-iso9798.pdf>.
[CapURLs]
Tennison, J., Ed., "Capability URL 的良好实践", W3C 首次公开工作草案, , <https://www.w3.org/TR/capability-urls/>.
[IANA.JWT.Claims]
IANA, "JSON Web Token (JWT)", <https://www.iana.org/assignments/jwt>.
[IANA.MediaTypes]
IANA, "媒体类型", <https://www.iana.org/assignments/media-types>.
[IANA.OAuth.Parameters]
IANA, "OAuth 参数", <https://www.iana.org/assignments/oauth-parameters>.
[OpenID.Core]
Sakimura, N., Bradley, J., Jones, M.B., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0 incorporating errata set 1", OpenID Foundation Standards, , <http://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>.
[RFC6819]
Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 威胁模型和安全 考虑事项", RFC 6819, DOI 10.17487/RFC6819, , <https://www.rfc-editor.org/info/rfc6819>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "媒体类型规范和 注册过程", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC6973]
Cooper, A., Tschofenig, H., Aboba, B., Peterson, J., Morris, J., Hansen, M., and R. Smith, "互联网协议的隐私 考虑事项", RFC 6973, DOI 10.17487/RFC6973, , <https://www.rfc-editor.org/info/rfc6973>.
[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>.
[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>.

致谢

以下人员在 OAuth 工作组和其他 IETF 角色中 为本文档的创建做出了贡献。 (使用的是贡献时的隶属关系。)

Annabelle Backman (Amazon), Dirk Balfanz (Google), Sergey Beryozkin, Ben Campbell (as AD), Brian Campbell (Ping Identity), Roman Danyliw (as AD), Martin Duke (as AD), Vladimir Dzhuvinov (Connect2id), Lars Eggert (as AD), Joel Halpern (as GENART), Benjamin Kaduk (as AD), Stephen Kent (as SECDIR), Murray Kucherawy (as AD), Warren Kumari (as OPSDIR), Watson Ladd (as SECDIR), Torsten Lodderstedt (yes.com), Jim Manico, James H. Manger (Telstra), Kathleen Moriarty (as AD), Axel Nennker (Deutsche Telecom), John Panzer (Google), Francesca Palombini (as AD), David Recordon (Facebook), Marius Scurtescu (Google), Luke Shepard (Facebook), Filip Skokan (Auth0), Hannes Tschofenig (ARM), Éric Vyncke (as AD), and Robert Wilton (as AD).

以下人员通过 OpenID Connect Core 1.0 [OpenID.Core] 为本文档的创建做出了贡献。

Brian Campbell (Ping Identity), George Fletcher (AOL), Ryo Itou (Mixi), Edmund Jay (Illumila), Breno de Medeiros (Google), Hideki Nara (TACT), and Justin Richer (MITRE).

作者地址

Nat Sakimura
NAT.Consulting
2-22-17 Naka
Kunitachi, Tokyo 186-0004
日本
电话: +81-42-580-7401
John Bradley
Yubico
Sucursal Talagante
Casilla 177
Talagante
RM
智利
电话: +1.202.630.5272
Michael B. Jones
Microsoft
One Microsoft Way
Redmond, Washington 98052
美利坚合众国