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 却依然支持?
这里需要区分“客户端认证”与“客户端标识”两个概念:
- 元数据的含义:
revocation_endpoint_auth_methods_supported列出的是 Keycloak 在该端点接受的客户端认证方式(如client_secret_basic、private_key_jwt等)。对于公共客户端,它不使用任何密钥进行“认证”,因此none作为一种认证方法通常不会出现在这个列表中。 - RFC 规范的要求:根据 OAuth 2.0 令牌撤销规范(RFC 7009),公共客户端的请求只需包含有效的
client_id,而机密客户端才需要提供有效的客户端凭据。 - Keycloak 的实际行为:Keycloak 遵循了这一规范。公共客户端在调用
/revoke端点时,只需在请求体中带上client_id和要撤销的token即可,无需任何密钥。有社区讨论也明确指出,公共客户端仅使用client_id撤销令牌是符合预期的正常行为,并被视为一项应保留的功能。
两者关系总结
简单来说:
token_endpoint_auth_method是“你要求这个客户端怎么认证”。revocation_endpoint_auth_methods_supported是“Keycloak 声明它的撤销接口支持哪些认证方式”。
当你在调用撤销接口时,所使用的认证方式必须符合 Keycloak 在元数据中声明的支持范围,并且通常应与该客户端在令牌端点配置的 token_endpoint_auth_method 保持一致(因为 Keycloak 的撤销端点通常复用相同的客户端认证机制)。
浙公网安备 33010602011771号