出示持有证明( DPoP )
DPoP 通过提供公私钥对的持有证明,该机制允许客户端获取受发件人限制的 OAuth 令牌。
该规范目前处于草案阶段: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-11。
DPoP HTTP 页眉
DPoP 标头是一个带签名的JWT,其中包含用于证明持有权的关键信息。
DPoP JWT 的 JOSE 标头必须至少包含以下参数:
| 参数 | 描述 |
|---|---|
| typ | JWT 的类型。 该值必须为“dpop+jwt”。 |
| ALG | 签名算法。 有效值包括: RS256、 RS384、 RS512、 PS256、 PS384、 PS512、 ES256、 ES384、 ES512 |
| JWK | 一个表示公钥的 JSON Web Key (JWK)。 不得包含私钥。 |
JOSE 标头示例:
{
"typ": "dpop+jwt",
"alg": "RS256",
"jwk": {
"kty": "RSA",
"n": "...",
"e": "AQAB"
}
}
DPoP JWT 的有效负载必须至少包含以下声明:
| 声明名称 | 描述 |
|---|---|
| jti | 此 JWT 的唯一标识符。 |
| htm | 附加了 JWT 的请求的 ` HTTP ` 方法。 |
| htu | HTTP 目标 URI,不包含查询字符串和片段部分。 这应该是“推送授权请求”(PAR)端点或令牌端点。 |
| iat | JWT 的创建时间戳。 |
JWT 有效负载示例:
{
"jti": "3765f59c-43cd-4cf8-8180-73bc9ae4ff3c",
"htm": "POST",
"htu": "https://<tenant-hostname>/oauth2/token",
"iat": 1661847227
}
DPoP 格式的JWT必须使用私钥进行签名,且该签名必须能够通过JWT的JOSE标头中提供的公钥进行验证。 JWT 的有效期不得超过 30 分钟。 如果没有 exp 声明,则该 JWT 的过期时间默认为在 iat. 中指定的创建时间戳之后 30 分钟。
JWT 通过名为 DPoP. 的标头发送。
请求示例:
curl -ki https://<tenantId>/oauth2/token
-H "DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6Il..."
-d "grant_type=client_credentials&client_secret=<secret>&client_id=<clientId>"
Authorize request
授权请求中包含 JSON Web Key 的指纹,该指纹位于查询参数或 POST 请求体中。
| 参数 | 描述 |
|---|---|
| dpop_jkt | 与该授权请求关联的 JSON Web Key 的指纹。 |
https://<tenantId>/oauth2/authorize?grant_type=authorization_code&client_id=<clientId>&redirect_uri=<redirect_uri>&dpop_jkt=<dpop_jkt>&...
为此请求生成的授权码将与该指纹绑定,并在请求令牌时用于验证。 这可以防止授权码被盗用,避免在将授权码兑换为代币时,被其他不具备相同私钥的实体用于签署代币请求。
建议结合使用推送式授权请求(PAR) 或请求对象与 DPoP, ,以安全的方式发送指纹 dpop_jkt 。 dpop_jkt此外,在使用 PAR 时,可以使用 ` DPoP ` 头部代替。 详情请参见 DPoP HTTP header 上文。 在配置 OpenID Connect应用程序时,可通过选择 Require pushed
authorization request (PAR) 来强制执行推送的授权请求。
代币请求
访问令牌和刷新令牌请求必须包含 DPoP HTTP 头部。 详情请参见 DPoP HTTP
header 上文。
对于授权码流程,此 JWK 的指纹必须与授权请求期间发送的 JWK 指纹 (dpop_jkt) 匹配。
请求示例:
curl -ki https://<tenantId>/oauth2/token
-H "DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6Il..."
-d "grant_type=client_credentials&client_secret=<secret>&client_id=<clientId>"
执行此流程的结果是一组与持有证明绑定的代币。 这可以通过令牌内省来验证。
令牌内省
- DPoPbearertoken_type: 该值应为 ,而非。
- cnf: JWK 拇指印验证方法会返回公钥的哈希值。
内省响应示例:
{
...,
"cnf": {
"jkt": "yrFAH18WFPml9e9IIo6rB_fLdFX1pdbMgIcd_fW_4aM="
},
"token_type": "DPoP",
...
}