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

容器化Spring Boot微服务网关Keycloak iss声明无效401错误求助

问题分析

你遇到的401错误确实是JWT的iss声明不匹配导致的:

  • 当你通过http://localhost:8890获取token时,Keycloak会将外部访问地址作为iss写入token,即http://localhost:8890/realms/my-realm
  • 但API网关在容器内部配置的issuer-uri是http://keycloak:8080/realms/my-realm,Spring Security OAuth2资源服务器会严格校验JWT的iss字段,两者不匹配就会返回401
解决方案

要解决这个问题,需要让Keycloak生成的JWT中的iss字段和网关配置的issuer-uri保持一致,具体可以通过配置Keycloak的hostname参数实现:

  1. 修改Keycloak的环境变量配置
    在你的keycloak.dev.env文件中添加以下配置:
KC_HOSTNAME=keycloak
KC_HOSTNAME_PORT=8080
KC_HOSTNAME_STRICT=false
KC_HOSTNAME_STRICT_HTTPS=false
  • KC_HOSTNAME:指定Keycloak的内部服务名(对应docker-compose中的服务名keycloak),让Keycloak生成的JWT中iss字段使用这个地址
  • KC_HOSTNAME_PORT:指定内部通信端口(Keycloak容器内部的8080端口)
  • KC_HOSTNAME_STRICT=false:允许外部通过localhost:8890访问Keycloak,但仍使用配置的hostname作为iss字段
  • KC_HOSTNAME_STRICT_HTTPS=false:开发环境下禁用HTTPS严格模式
  1. 重启容器
    执行以下命令重启Keycloak和API网关容器:
docker-compose down && docker-compose up -d
  1. 重新获取token并验证
    通过http://localhost:8890/realms/my-realm/protocol/openid-connect/token重新获取token,此时token中的iss字段会变为http://keycloak:8080/realms/my-realm,和网关配置的issuer-uri一致,再调用接口就不会出现401错误了。
备选方案(不推荐)

如果不想修改Keycloak配置,也可以修改API网关的issuer-uri为外部访问地址,但需要注意网关在容器内部需要能访问到这个地址,此时需要将网关的issuer-uri改为http://host.docker.internal:8890/realms/my-realm(针对Docker Desktop),但这种方式依赖宿主机的网络配置,不如第一种方案稳定。

内容的提问来源于stack exchange,提问作者Shanka Somasiri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:53:17