You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker环境下Keycloak user_info端点令牌验证失败问题排查

问题分析与解决方案

从你的描述和错误日志来看,核心问题大概率是Token的Issuer(发行者)不匹配导致Keycloak验证token失败,进而出现USER_INFO_REQUEST_ERROR且clientId/userId为空的情况。结合Docker Compose的网络特性,我整理了几个关键的排查和解决方向:

1. 修复Token Issuer与Keycloak内部地址的匹配问题

当用户在浏览器端通过localhost:28080完成授权时,Keycloak颁发的Token里的iss字段值是http://localhost:28080/auth/realms/cinema(假设你的realm是cinema)。但网关在Docker内部调用Keycloak的user-info-uri时用的是Docker内部的服务地址(比如http://keycloak:8080),这时候Keycloak验证Token时会发现Token的iss和自己的内部地址不匹配,直接判定为invalid_token,就会出现你看到的日志。

解决步骤:

  • 在Keycloak的Realm设置中,将Valid Redirect URIs和Web Origins同时配置外部访问地址(http://localhost:*)和Docker内部网关地址(比如http://gateway:8890/*)
  • 调整Keycloak的启动参数,让它兼容外部和内部的Issuer验证。在docker-compose.yml中给Keycloak服务添加以下环境变量:
    environment:
      - KC_HOSTNAME=localhost
      - KC_HOSTNAME_PORT=28080
      - KC_HOSTNAME_STRICT=false
      - KC_HOSTNAME_STRICT_HTTPS=false
      - KC_HTTP_ENABLED=true
    
    这样Keycloak会用localhost:28080作为Token的Issuer,同时关闭严格的Issuer检查(KC_HOSTNAME_STRICT=false),允许内部服务用keycloak:8080来验证Token。

2. 统一Gateway OAuth2配置的内部服务地址

你的配置里resourceserver.jwt.jwk-set-uri使用了${app.config.keycloak.url}变量,这个变量在Docker环境下必须指向Keycloak的内部DNS名称(比如http://keycloak:8080),而不是localhost。如果这个变量还是指向localhost,网关在验证JWT时会无法访问Keycloak的证书端点,间接导致Token验证异常。

调整后的配置片段:

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak-spring-gateway-client:
            token-uri: http://${KEYCLOAK:keycloak}:8080/auth/realms/${app.config.keycloak.realm}/protocol/openid-connect/token
            user-info-uri: http://${KEYCLOAK:keycloak}:8080/auth/realms/${app.config.keycloak.realm}/protocol/openid-connect/userinfo
            jwk-set-uri: http://${KEYCLOAK:keycloak}:8080/auth/realms/${app.config.keycloak.realm}/protocol/openid-connect/certs
      resourceserver:
        jwt:
          jwk-set-uri: http://${KEYCLOAK:keycloak}:8080/auth/realms/${app.config.keycloak.realm}/protocol/openid-connect/certs

3. 确认TokenRelay过滤器的配置正确性

TokenRelay过滤器负责将用户的Access Token转发到下游服务,但如果网关的OAuth2客户端配置存在问题,也可能导致Token传递异常:

  • 确保user-info-authentication-method: header配置正确,Keycloak默认支持通过Authorization头传递Token
  • 确认Keycloak中gateway客户端的类型是confidential,并且配置中的client-secret与Keycloak里的完全一致

4. 验证Docker网络的连通性

虽然你提到用了DNS名称,但还是要确认网关容器能正常访问Keycloak容器:

  • 进入网关容器,执行curl http://keycloak:8080/auth/realms/cinema,检查是否能返回Realm的公开信息
  • 如果无法访问,检查docker-compose中两个服务是否在同一个自定义网络下(默认的bridge网络也可以,但自定义网络更稳定)

内容的提问来源于stack exchange,提问作者pawel asdasdad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:30:41