keycloak~revoke端点介绍

revoke撤销令牌

支持。 尽管你看到的 revocation_endpoint_auth_methods_supported 元数据列表里没有 none,但这并不妨碍公共客户端(Public Client)调用撤销接口。公共客户端不需要(也没有)客户端密钥,它通过提供 client_id 来表明身份,Keycloak 的撤销端点接受这种认证方式。

公共客户端如何调用 revoke 接口?

公共客户端调用时,不需要 Authorization 头,直接在 POST 请求体中提供参数即可,如果是非public类型的客户端,需要在Authorization头中添加basic认证,带上client_id:client_secret信息。

请求示例(curl):

curl -X POST "https://keycloak.example.com/realms/{realm}/protocol/openid-connect/revoke" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=YOUR_TOKEN_HERE" \
  -d "token_type_hint=refresh_token" \
  -d "client_id=your-public-client-id"

关键点:

  • 必须包含 client_id。
  • public不需要 client_secret。
  • 要撤销的令牌必须属于该 client_id 对应的客户端。

revoke和logout的区别

在 Keycloak 中,/revoke 和 /logout 虽然都涉及让令牌失效,但设计目的、作用范围和规范归属有本质区别。核心差异在于:/revoke 主要用于令牌管理(且行为可能比预期激进),而 /logout 主要用于结束用户会话。

核心区别对比

规范与目的

  • /revoke:遵循 OAuth 2.0 Token Revocation (RFC 7009),目的是通知服务器某个令牌不再需要。
  • /logout:遵循 OpenID Connect RP-Initiated Logout,目的是结束用户在 Keycloak 的登录会话(SSO Session)。

关键行为与副作用

  • /revoke:行为可能具有“连带性”。在 Keycloak 中,撤销一个 Refresh Token 通常会连带撤销该用户对该客户端的授权同意(Consent),甚至可能终止相关的所有会话。这意味着用户下次登录可能需要重新同意授权。
  • /logout:主要终止会话。通过传入 refresh_token 的“传统”方式调用时,它仅关闭该特定令牌对应的那一个会话,不会影响同一用户的其他并行会话。

认证方式

  • /revoke:公共客户端只需提供 client_id;机密客户端需提供密钥。
  • /logout:通常通过浏览器重定向(携带 id_token_hint),或后端调用“传统”方式(需 client_id + refresh_token + 客户端认证)。

如何选择

  • 如果你只想安全地结束当前这一个设备的登录状态(例如用户点击“退出登录”),且不希望影响该用户在其他设备上的会话,推荐使用 /logout(传统后端调用方式),它更精准。
  • 如果你需要彻底撤销某个客户端的授权(例如用户想“解除绑定”或“断开连接”),或者需要确保与该授权相关的所有令牌和同意记录都被清除,那么 /revoke 是合适的选择,但需注意其可能带来的“连带注销”副作用。

token_endpoint_auth_method和revocation_endpoint_auth_methods_supported

这两个参数分别作用于 Keycloak 的客户端配置与服务器元数据发现两个不同层面,容易混淆,但职责分明。

token_endpoint_auth_method:客户端侧的认证方式选择

这是你在 Keycloak 中配置某个具体客户端时使用的一个属性。它决定了该客户端在调用令牌端点(/token)时,必须采用哪种方式向 Keycloak 证明自己的身份。

Keycloak 支持的主要取值包括:

  • client_secret_basic:客户端将 client_id 和 client_secret 通过 HTTP Basic 认证头(Authorization: Basic ...)发送。
  • client_secret_post:客户端将凭据放在 POST 请求体中发送。
  • private_key_jwt / client_secret_jwt:使用 JWT 进行客户端断言认证。
  • none:用于公共客户端(无密钥)。

作用与说明:
配置此项后,Keycloak 会强制该客户端在令牌端点使用指定的方式。例如,若设为 client_secret_post,客户端就不能再用 Basic 头来认证。需要注意的是,在较早版本或特定场景下(如动态客户端注册),Keycloak 可能曾同时允许两种方式,但新版本已趋向于严格执行配置。这与动态注册请求中客户端“期望”使用的方式有关,但本质仍是客户端自身的配置属性。

revocation_endpoint_auth_methods_supported:服务器侧的元数据声明

这个参数不是你直接配置的,而是 Keycloak 在授权服务器元数据(通常通过 /.well-known/oauth-authorization-server 或 /.well-known/openid-configuration 端点暴露)中自动生成的一个 JSON 数组。它的作用是告诉客户端(或开发者),Keycloak 的撤销端点(/revoke)支持哪些客户端认证方法。

技术细节:

  • 规范定义:它遵循 RFC 8414,是一个可选的元数据字段。如果缺失,默认值为 client_secret_basic。
  • Keycloak 的实现:在 Keycloak 的实现中,该列表的值通常与 token_endpoint_auth_methods_supported 保持一致,即令牌端点支持哪些认证方式,撤销端点也支持哪些。实际返回的列表可能包含 private_key_jwt、client_secret_basic、client_secret_post、tls_client_auth、client_secret_jwt 等。

为什么元数据里没有 none 却依然支持?

这里需要区分“客户端认证”与“客户端标识”两个概念:

  1. 元数据的含义:revocation_endpoint_auth_methods_supported 列出的是 Keycloak 在该端点接受的客户端认证方式(如 client_secret_basic、private_key_jwt 等)。对于公共客户端,它不使用任何密钥进行“认证”,因此 none 作为一种认证方法通常不会出现在这个列表中。
  2. RFC 规范的要求:根据 OAuth 2.0 令牌撤销规范(RFC 7009),公共客户端的请求只需包含有效的 client_id,而机密客户端才需要提供有效的客户端凭据。
  3. Keycloak 的实际行为:Keycloak 遵循了这一规范。公共客户端在调用 /revoke 端点时,只需在请求体中带上 client_id 和要撤销的 token 即可,无需任何密钥。有社区讨论也明确指出,公共客户端仅使用 client_id 撤销令牌是符合预期的正常行为,并被视为一项应保留的功能。

两者关系总结

简单来说:

  • token_endpoint_auth_method 是“你要求这个客户端怎么认证”。
  • revocation_endpoint_auth_methods_supported 是“Keycloak 声明它的撤销接口支持哪些认证方式”。

当你在调用撤销接口时,所使用的认证方式必须符合 Keycloak 在元数据中声明的支持范围,并且通常应与该客户端在令牌端点配置的 token_endpoint_auth_method 保持一致(因为 Keycloak 的撤销端点通常复用相同的客户端认证机制)。

posted @ 2026-10-22 08:53  张占岭  阅读(11)  评论(0)    收藏  举报