Keycloak 26.3.0数据库直接操作后用户持续遇401未授权错误
问题根源
直接对Keycloak数据库执行SQL删除操作会绕过Keycloak的内部缓存机制与数据一致性校验,导致以下核心问题:
- 仅清理了离线会话,但未处理在线用户会话、客户端会话及认证流程相关的持久化数据,Keycloak缓存中仍残留无效的会话/凭证引用
- 浏览器端留存的旧Session Cookie、Refresh Token等凭证未被失效,用户登录时这些旧凭证会被提交至Keycloak,触发会话校验失败
- 分布式部署下,Infinispan缓存(默认用于跨Pod会话共享)可能仍存有过期数据,单纯缩容Pod无法完全清除集群缓存
分步解决方案
1. 补全数据库会话/数据清理(仅用于紧急修复场景)
除已执行的SQL外,需补充清理在线会话及认证相关表:
-- 清理在线用户会话 DELETE FROM USER_SESSION WHERE USER_ID IN ( SELECT ID FROM USER_ENTITY WHERE USERNAME IN (<ALL_USERNAMES>) ); -- 清理在线客户端会话 DELETE FROM CLIENT_SESSION WHERE USER_SESSION_ID IN ( SELECT ID FROM USER_SESSION WHERE USER_ID IN ( SELECT ID FROM USER_ENTITY WHERE USERNAME IN (<ALL_USERNAMES>) ) ); -- 清理认证会话缓存数据 DELETE FROM AUTH_SESSION_TABLE WHERE USER_ID IN ( SELECT ID FROM USER_ENTITY WHERE USERNAME IN (<ALL_USERNAMES>) ); -- 清理持久化认证数据(用于记住登录等场景) DELETE FROM PERSISTED_AUTHENTICATION WHERE USER_ID IN ( SELECT ID FROM USER_ENTITY WHERE USERNAME IN (<ALL_USERNAMES>) );
2. 强制刷新Keycloak分布式缓存
缩容Pod无法保证清除Infinispan集群缓存,需通过Keycloak Admin API或CLI主动清除目标用户的缓存:
使用Admin API(需先获取管理员令牌):
# 获取管理员令牌 curl -X POST "http://<keycloak-host>/realms/master/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=<admin-user>" \ -d "password=<admin-pass>" \ -d "grant_type=password" \ -d "client_id=admin-cli" # 清除目标用户的缓存 curl -X DELETE "http://<keycloak-host>/admin/realms/<your-realm>/users/<user-id>/cache" \ -H "Authorization: Bearer <admin-token>"批量处理可循环遍历用户ID执行上述删除请求。
使用Keycloak CLI(kc.sh):
kc.sh adm users clear-cache --realm <your-realm> --user <user-id>
3. 强制注销用户所有会话
通过Keycloak控制台或API强制注销用户的所有会话,使客户端/浏览器端的旧凭证失效:
- 控制台操作:进入目标用户详情页 → 会话标签 → 点击注销所有会话
- API操作:
curl -X POST "http://<keycloak-host>/admin/realms/<your-realm>/users/<user-id>/logout" \ -H "Authorization: Bearer <admin-token>"
4. 规范后续操作流程
禁止直接操作Keycloak数据库,改用官方推荐方式处理用户凭证与会话:
- 删除用户凭证:使用Admin API
/admin/realms/{realm}/users/{id}/credentials/{credential-id}或控制台删除 - 注销用户会话:使用上述注销API或控制台操作
- 批量操作:编写脚本调用Admin API实现批量处理,避免直接数据库操作带来的一致性问题
验证步骤
- 执行完上述清理与缓存刷新操作后,让用户无需清除浏览器缓存直接尝试登录
- 检查Keycloak日志,确认不再出现
REFRESH_TOKEN_ERROR、Session Not Found等错误 - 验证OAuth回调流程正常返回令牌
内容的提问来源于stack exchange,提问作者Ismail Muhammad




