Keycloak:从内部 docker 容器运行时令牌颁发者无效

Posted

技术标签:

【中文标题】Keycloak:从内部 docker 容器运行时令牌颁发者无效【英文标题】:Keycloak: Invalid token issuer when running from internal docker container 【发布时间】:2021-06-16 22:20:27 【问题描述】:

我在配置 keycloak 以在我们的服务器上运行时遇到了一些问题。 在本地它工作得很好,但在我们的测试环境中,登录后,在使用接收到的访问令牌的任何调用中,我们得到“无效的令牌颁发者。预期的“http://keycloak:8080/auth/realms/realmnName”但是"http://our-test-server-IP/auth/realms/realmName"" 所以基本上,我们的后端连接到内部 keycloak docker 映像,但是当请求到来时,它期望发行者是配置的外部 IP,因此即使发行者基本上是相同的服务 keycloak 也会将它们视为不同并以 401 响应。

docker-compose.yml:

keycloak:
    image: jboss/keycloak:12.0.4
    restart: on-failure
    environment:
        PROXY_ADDRESS_FORWARDING: "true"
        KEYCLOAK_USER: admin
        KEYCLOAK_PASSWORD: password
        KEYCLOAK_LOGLEVEL: DEBUG
        KEYCLOAK_IMPORT: /etc/settings/realm.json -Dkeycloak.profile.feature.upload_scripts=enabled
        TZ: Europe/Bucharest
        DB_VENDOR: POSTGRES
        DB_ADDR: db
        DB_DATABASE: user
        DB_SCHEMA: keycloak
        DB_USER: user
        DB_PASSWORD: user
    ports:
        - 8090:8080
    volumes:
        - ./settings:/etc/settings
    depends_on:
        - db

Spring application.yml:

keycloak:
  cors: true
  realm: Realm-Name
  resource: back-office
  auth-server-url: http://keycloak:8080/auth/
  public-client: false
  credentials:
    secret: 8401b642-0ae9-4dc8-87a6-2f494b388a49

keycloak-client:
  id: bcc94ed5-0099-40e0-b460-572eba3f0214

如果我们更改后端属性 auth-server-url 以连接到暴露的端点,而不是连接到内部 docker 容器,我们会得到超时,似乎它不想连接到它。我知道主要问题是我们在同一台服务器上同时运行 keycloak 实例和后端应用程序,但我不明白为什么它不应该工作以及为什么它们无法相互连接。

我们尝试在运行容器和 Keycloak 管理控制台时在环境中设置 FRONTEND_URL,但没有任何改变。我们还尝试在standalone.xml/standalone-ha.xml(./jboss-cli.sh --connect "/subsystem=keycloak-server/spi=hostname/provider=default:write-attribute 中将 forceBackendUrlToFrontendUrl 设置为 true (name=properties.forceBackendUrlToFrontendUrl, value=true)") 文件并使用 ./jboss-cli.sh --connect command=:reload 重置 docker 容器内的 keycloak 实例,但没有任何改变。

我知道,基本上通过设置 FRONTEND_URL,所有令牌都应该由 keycloak 实例签名,我们不会遇到这个问题,但我已经尝试了迄今为止在这个问题上找到的关于 keycloak 配置的所有内容,但似乎没有改变事情。如何确保签署访问令牌的颁发者和后端服务期望的颁发者相同(希望是前端)?我该如何配置它,是否缺少某些属性或者我在配置时做错了什么?

【问题讨论】:

你用“keycloak”掩盖了你的真实域名,或者这是从哪里来的? keycloak:8080 指的是 docker 镜像。后端运行在同一个网络中,所以它可以通过 docker 镜像名称来引用它 找到解决这个问题的方法了吗? @William 不是真的,没有任何建议对我有用。有一次,我们刚刚重新启动了后端服务器,它突然又重新工作了——所以这可能比我最初想象的要容易得多。为了避免这个问题,我们计划在未来部署在不同的服务器上 【参考方案1】:

可能与这里的答案有关:https://***.com/a/64095482/13494285

您可以将 Host 标头值设置为预期的 url。

要覆盖此行为,您可以尝试将 KEYCLOAK_HOSTNAME 环境变量设置为预期的 url。

似乎文档可能不是最新的(它建议here 上的KEYCLOAK_FRONTEND_URL 变量),而是使用KEYCLOAK_HOSTNAME 设置fixed 提供程序,如here. 上所示

在这种情况下,还需要 KEYCLOAK_HTTP_PORT 将端口设置为 8080

【讨论】:

我已经尝试更改 Jira 票证中的属性,希望发送的 issuer 和 realmUrl 都是 frontendUrl,但我要么没有正确执行,要么它不起作用。您的意思是使用 keycloak:8080 覆盖每个请求的 Host http 标头? 最近好像那个变量被命名为KEYCLOAK_FRONTEND_URL,你试过吗? github.com/keycloak/keycloak-containers/blob/12.0.4/server/… 是的,关于覆盖的问题。 是的,已经尝试设置 KEYCLOAK_FRONTEND_URL 但它什么也没做:( 嗯。 KEYCLOAK_HOSTNAME 变量仍然基于代码使用,如果你还没有尝试过的话。 github.com/keycloak/keycloak-containers/blob/…【参考方案2】:

将 KEYCLOAK_HOSTNAME 设置为外部主机名(在 KEYCLOAK_FRONTEND_URL 中定义)绝对适用于我的案例(在 vanilla kubernetes 集群上安装 eclipse che)

【讨论】:

以上是关于Keycloak:从内部 docker 容器运行时令牌颁发者无效的主要内容,如果未能解决你的问题,请参考以下文章

如何将领域文件导出到 keycloak docker 容器中?

代理从 nginx 容器传递到 keycloak 容器时获取 502 Bad gateway

Docker/Symfony/Reactjs/Keycloak:如何使用分离的 docker-compose 文件从一个容器向另一个容器发出 HTTP 请求?

Keycloak Docker 容器重启后无法启动

Docker(Spring Boot 或 Thorntail)和 Keycloak

M1 mac 无法运行 jboss/keycloak docker 镜像