Keycloak:使用有效访问令牌调用userinfo端点出现Key not found错误
以下是针对该问题的具体排查方向和解决方案:
检查令牌受众(aud)是否包含必要客户端ID
解析访问令牌查看aud字段,Keycloak的userinfo接口默认要求令牌受众包含account客户端(该接口归属于account客户端的权限范围)。如果你的令牌aud列表中没有account,即使密钥匹配,也会触发验证失败。解决方式:在客户端配置的Client Scopes中添加account客户端范围,或开启Full Scope Allowed选项,让令牌自动包含默认权限范围。确认容器内Keycloak密钥状态与存储同步
通过docker进入Keycloak容器,使用kcadm.sh工具查看领域密钥列表:# 先获取admin令牌(替换admin用户名、密码、领域名) kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin # 查看目标领域的密钥 kcadm.sh get realms/<你的领域名>/keys确认对应
kid的密钥状态为ACTIVE,且存在于列表中。如果密钥缺失,可尝试重启Keycloak容器,确保容器内的密钥存储(如默认H2数据库)正常加载。验证签名算法的完全匹配性
再次核对JWT头中的alg字段与/protocol/openid-connect/certs端点返回的对应kid的alg值,需完全一致(注意大小写和格式,避免缩写与全称不匹配的情况,比如RS256与RSASSA-PKCS1-v1_5)。检查cURL请求的令牌传递方式
确保请求时正确使用Authorization头传递令牌,避免令牌存在格式错误(如多余空格、换行):curl -H "Authorization: Bearer <你的访问令牌>" http://<Keycloak地址>/realms/<你的领域名>/protocol/openid-connect/userinfo可通过以下命令解析令牌,确认
kid和内容无误:echo <你的访问令牌> | jq -R 'split(".")[:2] | map(@base64d) | map(fromjson)'排查领域密钥配置的异常状态
进入Keycloak领域的Keys页面,检查对应kid的密钥是否为ACTIVE状态,未被标记为REVOKED或INACTIVE;同时确认不存在多个相同kid的密钥(重复密钥可能导致Keycloak无法定位正确的签名密钥)。检查Keycloak启动参数的影响
查看docker-compose.yml中的Keycloak启动参数,是否存在影响密钥加载的配置(如缓存相关参数)。尝试重启Keycloak容器,重置内存中的密钥缓存,看是否能解决问题。
内容的提问来源于stack exchange,提问作者DPWork

