2. 令牌撤销
2. 令牌撤销 (Token Revocation)
实现必须 (MUST) 支持 refresh token 的撤销, 并且应该 (SHOULD) 支持 access token 的撤销 (见 Implementation Note).
客户端通过向 token revocation endpoint URL 发出 HTTP POST 请求来请求撤销某个特定 token. 该 URL 必须 (MUST) 符合 [RFC6749] 第 3.1 节给出的规则. 客户端必须 (MUST) 验证该 URL 是 HTTPS URL.
获取 revocation endpoint 位置的方法超出本规范范围. 例如, 客户端开发者可以查阅服务器文档, 或使用自动发现. 由于此 endpoint 处理安全凭据, endpoint 位置需要从可信来源获取.
由于发送到 token revocation endpoint 的请求会在 HTTP 请求中传输明文凭据, token revocation endpoint 的 URL 必须 (MUST) 是 HTTPS URL. authorization server 必须 (MUST) 使用符合 [RFC6749] 第 1.6 节要求版本的 Transport Layer Security (TLS) [RFC5246]. 实现也可以 (MAY) 支持满足其安全需求的其他传输层安全机制.
如果 token revocation endpoint 的主机也可以通过 HTTP 到达, 则服务器也应该 (SHOULD) 在对应的 HTTP URI 上提供撤销服务, 但不得 (MUST NOT) 将此 URI 发布为 token revocation endpoint. 这可以确保意外通过 HTTP 发送的 token 会被撤销.
2.1. 撤销请求 (Revocation Request)
客户端使用 "application/x-www-form-urlencoded" 格式在 HTTP request entity-body 中包含以下参数来构造请求:
token : REQUIRED. 客户端希望撤销的 token.
token_type_hint : OPTIONAL. 关于提交撤销的 token 类型的提示. 客户端可以 (MAY) 传递此参数, 以帮助 authorization server 优化 token 查找. 如果服务器无法使用给定提示定位 token, 则它必须 (MUST) 将搜索扩展到其支持的所有 token 类型. authorization server 可以 (MAY) 忽略此参数, 特别是在它能够自动检测 token 类型时. 本规范定义了两个这样的值:
-
access_token: [RFC6749] 第 1.4 节定义的 access token -
refresh_token: [RFC6749] 第 1.5 节定义的 refresh token
本规范的特定实现, profile 和扩展可以 (MAY) 使用第 4.1.2 节定义的注册表为此参数定义其他值.
客户端还按 [RFC6749] 第 2.3 节所述包含其认证凭据.
例如, 客户端可以使用以下请求来请求撤销 refresh token:
POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token
authorization server 首先验证客户端凭据 (对于 confidential client), 然后验证该 token 是否签发给了发出撤销请求的客户端. 如果此验证失败, 请求将被拒绝, authorization server 会按下文所述将错误告知客户端.
下一步, authorization server 使 token 失效. 失效会立即发生, token 在撤销后不能再次使用. 实践中可能存在传播延迟, 例如一些服务器知道该失效, 而另一些服务器尚不知道. 实现应该尽量缩小这一窗口, 客户端在收到服务器的 HTTP 200 响应后不得尝试使用该 token.
根据 authorization server 的撤销策略, 某个特定 token 的撤销可能导致相关 token 及其底层 authorization grant 被撤销. 如果该特定 token 是 refresh token, 并且 authorization server 支持 access token 撤销, 则 authorization server 还应该 (SHOULD) 使基于同一 authorization grant 的所有 access token 失效 (见 Implementation Note). 如果请求中传递的 token 是 access token, 服务器也可以 (MAY) 撤销相应的 refresh token.
注意: 符合 [RFC6749] 的客户端必须准备好随时处理意外的 token 失效. 独立于本文档规定的撤销机制, resource owner 可以撤销 authorization grant, 或 authorization server 可以为了缓解安全威胁而使 token 失效. 因此, 服务器在 token 级联撤销方面具有不同策略不应造成互操作性问题.
2.2. 撤销响应 (Revocation Response)
如果 token 已成功撤销, 或客户端提交了无效 token, authorization server 都以 HTTP status code 200 响应.
注意: 无效 token 不会导致错误响应, 因为客户端无法以合理方式处理这种错误. 此外, 撤销请求的目的, 即使该特定 token 失效, 已经达成.
客户端会忽略响应体内容, 因为所有必要信息都已由响应代码传达.
authorization server 会忽略无效的 token type hint 值, 且该值不会影响撤销响应.
2.2.1. 错误响应 (Error Response)
错误表示符合 [RFC6749] 第 5.2 节中的定义. 为 token revocation endpoint 定义以下附加错误码:
unsupported_token_type : authorization server 不支持撤销所呈现的 token 类型. 也就是说, 客户端试图在不支持此功能的服务器上撤销 access token.
如果服务器以 HTTP status code 503 响应, 客户端必须假定 token 仍然存在, 并可以在合理延迟后重试. 服务器可以在响应中包含 "Retry-After" 头部, 以指示预计该服务对请求客户端不可用的时长.
2.3. 跨源支持 (Cross-Origin Support)
如果 revocation endpoint 旨在与基于 user-agent 的应用结合使用, 则它可以 (MAY) 支持 Cross-Origin Resource Sharing (CORS) [W3C.WD-cors-20120403].
此外, 为了与旧版 user-agent 互操作, 它也可以 (MAY) 通过允许带有附加参数的 GET 请求来提供 JSONP (Remote JSON - JSONP) [jsonp]:
callback : OPTIONAL. JavaScript 函数的限定名称.
例如, 客户端可以使用以下请求来请求撤销 access token (换行仅用于显示):
https://example.com/revoke?token=agabcdefddddafdd&
callback=package.myCallback
成功响应:
package.myCallback();
错误响应:
package.myCallback({"error":"unsupported_token_type"});
客户端应该意识到, 当依赖 JSONP 时, 恶意 revocation endpoint 可能试图向客户端注入恶意代码.