Keycloak 和 Spring 在 dockerized 环境中启动网络应用程序

Keycloak and Spring Boot web app in dockerized environment

考虑以下环境:

Web 应用程序是一个 Spring 启动应用程序,应用了 "keycloak-spring-boot-starter"。在 application.properties:

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

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

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

曾经有另一个 属性 auth-server-url-for-backend-requests 但现在是 removed by pull request #2506 as a solution to issue #2623 on Keycloak's JIRA。在此问题的描述中,您会找到原因和可能的解决方法:应该在 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,您可以使用 docker network connect 命令的 --alias 标志来执行 the equivalent(请参阅文档:容器网络/IP 地址和主机名).