5. DPoP Access Token Request (DPoP 访问令牌请求)
5. DPoP Access Token Request (DPoP 访问令牌请求)
为了请求被绑定到使用 DPoP 的公钥的访问令牌,客户端在向授权服务器的令牌端点发出访问令牌请求时,必须在 DPoP 头部中提供有效的 DPoP 证明 JWT。这适用于所有访问令牌请求,无论授权类型如何(例如,常见的 authorization_code 和 refresh_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 头字段必须包含有效的 DPoP 证明 JWT。如果 DPoP 证明无效,授权服务器将根据 [RFC6749] 第 5.2 节发出错误响应,其中错误参数的值为 invalid_dpop_proof。
为了在检查 DPoP 证明的有效性后对访问令牌进行发送者约束,授权服务器将颁发的访问令牌与 DPoP 证明中的公钥相关联,这可以通过第 6 节中描述的方式完成。token_type 为 DPoP 必须包含在访问令牌响应中,以向客户端发出信号,表明访问令牌已绑定到其 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 证明的公共客户端颁发刷新令牌时,刷新令牌必须绑定到相应的公钥。稍后出示刷新令牌以获取新访问令牌时,必须验证该绑定。因此,每当使用该刷新令牌获取新访问令牌时,此类客户端必须为获得该刷新令牌时使用的同一密钥出示 DPoP 证明。绑定刷新令牌的实现细节由授权服务器自行决定。由于授权服务器既生成又验证其刷新令牌,因此绑定的具体细节不存在互操作性考虑。
授权服务器可以选择颁发未绑定 DPoP 的访问令牌,根据 [RFC6750],通过访问令牌响应的 token_type 参数中的 Bearer 值向客户端发出信号。对于同时也获得刷新令牌的公共客户端,这具有仅对刷新令牌进行 DPoP 绑定的效果,即使受保护资源未更新以支持 DPoP,也可以改善安全状况。
如果访问令牌响应包含不同于 DPoP 的 token_type 值,则不提供 DPoP 提供的访问令牌保护。如果这种保护被认为对应用程序的安全性很重要,则客户端必须在这种情况下丢弃响应;否则,客户端可以像在常规 OAuth 交互中那样继续。
发给机密客户端(已与授权服务器建立身份验证凭据的客户端)的刷新令牌不绑定到 DPoP 证明公钥,因为它们已经通过不同的现有机制进行了发送者约束。OAuth 2.0 授权框架 [RFC6749] 已经要求授权服务器将刷新令牌绑定到颁发给它们的客户端,并且机密客户端在出示刷新令牌时向授权服务器进行身份验证。因此,此类刷新令牌通过客户端标识符和关联的身份验证要求进行发送者约束。这种现有的发送者约束机制比直接绑定到特定公钥更灵活(例如,它允许在不使刷新令牌无效的情况下轮换客户端的凭据)。
5.1. 授权服务器元数据
本文档介绍了以下授权服务器元数据 [RFC8414] 参数,以表明总体上对 DPoP 的支持以及授权服务器对 DPoP 证明 JWT 支持的特定 JWS alg 值。
dpop_signing_alg_values_supported: 一个 JSON 数组,包含授权服务器对 DPoP 证明 JWT 支持的 JWS alg 值(来自 [IANA.JOSE.ALGS] 注册表)列表。
5.2. 客户端注册元数据
动态客户端注册协议 [RFC7591] 定义了一个 API,用于向授权服务器动态注册 OAuth 2.0 客户端元数据。[RFC7591] 定义的元数据及其注册扩展也暗示了一种通用的客户端数据模型,即使不使用动态客户端注册协议,该模型对授权服务器实现也很有用。此类实现通常会有某种类型的用户界面可用于管理客户端配置。
本文档介绍了以下客户端注册元数据 [RFC7591] 参数,以指示客户端在从授权服务器请求令牌时始终使用 DPoP。
dpop_bound_access_tokens: 一个布尔值,指定客户端是否始终对令牌请求使用 DPoP。如果省略,默认值为 false。
如果该值为 true,授权服务器必须拒绝来自该客户端的不包含 DPoP 头部的令牌请求。