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

Spring Boot+Keycloak部署Docker后调用安全接口返回401问题

问题原因分析与解决方案

1. JWT Issuer声明与应用配置不匹配(最可能原因)

  • 容器外运行时,你肯定是通过http://localhost:8000/realms/polsl-course-api访问Keycloak获取JWT,此时JWT里的iss(签发者)字段值就是这个地址。
  • 但容器内的Spring Boot应用配置的issuer-uri是http://keycloak:8080/realms/polsl-course-api,Spring Security OAuth2资源服务器会严格校验JWT的iss字段与配置的issuer-uri是否完全一致,不一致则直接返回401。

解决办法:
统一Issuer地址,推荐修改Keycloak配置让它生成的JWT使用你本地访问的地址:

  • 给keycloak服务添加两个环境变量:KC_HOSTNAME=localhost和KC_HOSTNAME_PORT=8000,这样Keycloak生成的JWT的iss字段会是http://localhost:8000/realms/polsl-course-api。
  • 同时修改application-docker.yaml里的issuer-uri为http://localhost:8000/realms/polsl-course-api,确保容器内应用能通过该地址访问Keycloak(Docker会把localhost映射到主机)。

修改后的keycloak配置片段:

keycloak:
  # 其他原有配置保留
  environment:
    # 原有环境变量保留
    KC_HOSTNAME: localhost
    KC_HOSTNAME_PORT: 8000

修改后的application-docker.yaml配置:

security:
  oauth2:
    resourceserver:
      jwt:
        issuer-uri: http://localhost:8000/realms/polsl-course-api

2. 应用启动早于Keycloak服务就绪

  • depends_on仅保证Keycloak容器启动,但不代表Keycloak的服务已经初始化完成并能正常响应请求。如果Spring Boot应用先启动,可能无法获取Keycloak的JWKS(JSON Web密钥集),导致无法验证JWT签名,返回401。
  • 你可以开启Spring Security的DEBUG日志,查看是否有获取JWKS失败的记录,当前日志无有效信息的情况下,DEBUG级别日志能暴露更多细节。

解决办法:

  • 给schedule-service添加启动前等待脚本,比如用curl轮询Keycloak的/realms/polsl-course-api/.well-known/openid-configuration端点,直到能正常返回数据再启动应用。
  • 或者在应用配置中添加JWKS获取的重试机制,增加重试次数和间隔时间。

3. 容器间网络连通性问题(概率较低)

  • 虽然Docker Compose默认会给所有服务分配同一网络,但不排除网络配置异常导致schedule-service无法访问keycloak容器的情况。如果连Keycloak的配置端点都访问不了,自然无法验证JWT。

解决办法:

  • 进入schedule-service容器,执行命令curl http://keycloak:8080/realms/polsl-course-api/.well-known/openid-configuration,检查是否能正常返回OpenID配置信息。如果访问失败,排查Docker网络配置是否正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:49:56