dockerized 环境中的 Keycloak 和 Spring Boot Web 应用程序

Posted

技术标签:

【中文标题】dockerized 环境中的 Keycloak 和 Spring Boot Web 应用程序【英文标题】:Keycloak and Spring Boot web app in dockerized environment 【发布时间】:2019-12-04 10:03:44 【问题描述】:

考虑以下环境:

一个 docker 容器是 keycloak 另一个 docker 容器是我们使用 keycloak 进行身份验证的 Web 应用程序

Web 应用程序是应用了“keycloak-spring-boot-starter”的 Spring Boot 应用程序。在 application.properties 中:

keycloak.auth-server-url = http://localhost:8028/auth

访问我们的网络应用程序的用户将使用 keycloak docker 容器的公开端口的 URL 重定向到 keycloak。登录在 keycloak 中没有问题,并且用户(浏览器)再次被重定向到我们的 Web 应用程序。现在,需要将授权码交换为访问令牌。因此,我们的网络应用程序(keycloak 客户端)尝试连接到 keycloak.auth-server-url 中配置的相同主机和端口。但这是一个问题,因为 Web 应用程序驻留在 docker 容器中,而不是在主机上,因此它应该访问 http://keycloak:8080 或链接 keycloak 的地方keycloak docker 容器。

所以问题是:如何配置 keycloak 客户端以应用不同的 URL 进行浏览器重定向和访问令牌端点?

【问题讨论】:

【参考方案1】:

曾经有另一个属性auth-server-url-for-backend-requests,但作为issue #2623 on Keycloak's JIRA 的解决方案是removed by pull request #2506。在此问题的描述中,您将找到原因和可能的解决方法:应该在 DNS 级别或通过向主机文件添加条目来解决

所以在客户端配置中你无能为力,除非你更改代码并制作你自己的适配器版本,但你可以在 Docker 级别做一些事情。为了使其正常工作,首先我建议您使用完全限定的域名而不是 localhost 作为 public 主机名,就像在生产中一样,例如。 keycloak.mydomain.com。如果您只是将它添加到主机的 /etc/hosts 文件(或 Windows 等效文件)作为 localhost 旁边的别名,则可以使用假的(未在 DNS 服务器中注册)。

然后,如果您使用的是 Docker Compose,您可以为容器所连接的 docker 网络上的 keycloak 服务设置 aliases(替代主机名)(请参阅文档:撰写文件参考/服务配置参考/网络/别名)。例如:

version: "3.7"

services:
  keycloak:
    image: jboss/keycloak
    networks:
      # Replace 'mynet' with whatever user-defined network you are using or want to use
      mynet:
        aliases:
          - keycloak.mydomain.com

  webapp:
    image: "nginx:alpine"
    networks:
      - mynet

networks:
  mynet:

如果您只是使用普通 Docker,您可以使用 --alias 标志 docker network connect 命令执行 the equivalent(请参阅文档:容器网络/IP 地址和主机名)。

【讨论】:

感谢您的回答。在测试这种方法时,我必须将 8080 上的 keycloak 端口暴露给我的 docker 主机,因为从浏览器和我的 webapp 访问该端口必须相同。所以我需要假设这个端口在 docker 主机上总是可用的,还是我错过了什么? 是的,我假设在两种情况下都使用相同的端口(从外部浏览器访问或从 webapp docker 容器访问)。您可以使用不同的端口,例如。通过将 webapp 放在重写“Location”标头(例如 Nginx + http_proxy_module 的 proxy_redirect 指令)的反向代理后面,以仅更改来自 webapp 的代理重定向响应中的 keycloak 服务器端口(仅此而已),但我不是确定 Keycloak 是否会接受在一个端口上获取代码/令牌,然后在另一个端口上重用它。待测试。 这非常适合使用 keycloak 在本地机器上测试 compose 环境。谢谢! 如果设置一个指向 127.0.0.1 的 localhost.mydomain.com 之类的 dns 条目,则可以更轻松地对非技术人员进行测试 - 只要人们在线,它就可以在不修改他们的 /etc/hosts 文件的情况下工作

以上是关于dockerized 环境中的 Keycloak 和 Spring Boot Web 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Keycloak Docker 容器重启后无法启动

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

docker 容器中的 Keycloak + 主机上的 MySQL 提供 [org.keycloak.services] (ServerService 线程池 -- 62) 无法连接到数据库

使用 docker-compose 时导入 keycloak 配置文件

在 plesk 的 docker 容器上运行 keycloak 服务器的问题

在 Nginx 代理后面时,Keycloak Docker Instace 中的 X-Frame-Options 拒绝加载