Keycloak+Go gocloak令牌自省返回active:false问题排查
问题结论
你怀疑的「获取令牌与令牌自省的访问地址主机名不一致导致校验失败」的判断完全不准确,当前自省返回active: false的核心原因是你传的根本不是合法的OAuth2访问令牌。
核心故障原因
你从浏览器Cookie中提取的KEYCLOAK_IDENTITY值,是Keycloak自身用于维护用户浏览器会话的加密Cookie,仅对Keycloak服务本身有效,不属于OAuth2/OpenID Connect规范中定义的、可用于业务API鉴权的access_token,自然无法通过令牌自省接口的校验。
- 服务启动阶段通过
LoginClient拿到的是标准服务账号模式颁发的合法access_token,所以自省可以正常通过,这也能侧面证明Go服务和Keycloak之间的网络连通、客户端配置、自省接口调用逻辑都是正常的,和访问用的主机名没有任何关系。 - 令牌自省的逻辑是后端服务把令牌字符串传给Keycloak的自省端点,Keycloak仅校验令牌的签名、有效期、签发方、受众、撤销状态等内置属性,完全不关心调用方是通过什么域名拿到的令牌,也不关心调用自省接口时用的是容器名还是localhost地址,只要请求能打到正确的Keycloak realm端点、客户端凭证正确即可。
正确的测试方式
要测试用户态请求的鉴权逻辑,不要从浏览器Cookie中抠取值,走标准流程拿合法access_token即可:
- 可以直接在Postman中配置OAuth2.0授权,填写对应realm的授权端点、令牌端点、ClientID、ClientSecret,走浏览器跳转完成谷歌账号登录后,Postman会自动拿到合法的access_token,放到请求的
Authorization: Bearer <token>头中调用Go接口即可。 - 测试环境也可以通过Keycloak提供的密码模式授权接口,传对应用户的用户名密码换access_token做测试,生产环境不推荐开启该模式。
统一主机名的配置方法(可选,解决你提到的访问地址不一致问题)
如果你确实需要让宿主机和Docker容器内部用同一个域名访问Keycloak,按以下步骤配置即可:
- 确保Keycloak容器和Go API服务在同一个Docker自定义网络中,容器内部默认就可以通过容器名
keycloak直接解析访问。 - 修改宿主机的hosts文件,添加一条记录:
127.0.0.1 keycloak
- 把Keycloak容器的8080端口映射到宿主机的8080端口,此时不管是容器内部还是宿主机,都可以通过
http://keycloak:8080访问到Keycloak服务,地址完全统一。
代码侧需要补全的问题
你当前的鉴权中间件逻辑有明显漏洞,需要修正:
- 调用
RetrospectToken返回err时,不能只打日志,要直接终止请求返回401,否则会出现空指针panic或者非法请求透传的问题。 - 自省返回结果后,必须先判断
token.Active的布尔值,为false时直接返回401,不要继续往后执行业务逻辑。 - 注意核对Keycloak版本的端点前缀:17+版本的Quarkus发行版默认去掉了
/auth路径前缀,如果你用的是新版本,所有接口地址要去掉/auth避免404。
内容的提问来源于stack exchange,提问作者aescript
相关产品推荐
相关产品推荐

