如何在 NGINX 入口后面的 Keycloak 中更改 fronend URL?

How to change fronend URL in Keycloak behind NGINX ingress?

我可以在互联网上找到很多这样的问题,但是 none 提供的解决方案有效。

我正在使用 jboss/keycloak:14.0.0 docker 图片。在我的 ConfigMap:

中设置了以下属性
KEYCLOAK_FRONTEND_URL: /mycontext/access-management
PROXY_ADDRESS_FORWARDING: "true"

请注意,将 KEYCLOAK_FRONTEND_URL 更改为绝对 URL 像这样 https://mycompany.com/mycontext/access-managemen 没有区别。

现在入口定义如下:

Path: /mycontext/access-management(/|$)(.*)
Rewrite To: /
Annotations:
    ingress.kubernetes.io/ssl-redirect: "False"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Request-ID $request_id;
      proxy_set_header X-Trace-ID $request_id;
      gzip off;
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "180"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "180"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "180"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header X-Request-ID $request_id;
      add_header X-Trace-ID $request_id;
    nginx.org/redirect-to-https: "True"

发生的事情很奇怪。请看下面,它向您展示了当我点击 URL:

时它带我去了哪里
Go to [server]/mycontext/access-management =takes you to=> [server]/auth
Go to [server]/mycontext/access-management/auth =takes you to=> [server]/mycontext/access-management/auth (works fine)

如您所见,第二个 link 工作正常,您可以看到 Keycloak 欢迎页面,其中包含许多 link。 link 之一是 Administration Console 已损坏。如果您将鼠标悬停,则 link 是 [server]/mycontext/access-management/admin 而不是 [server]/mycontext/access-management/auth/admin(将其与我的本地 Keycloak 服务器进行比较)。现在,如果我们忽略 link 并将正确的路径作为 [server]/mycontext/access-management/auth/admin 放在地址栏中,则会发生另一件奇怪的事情,这会将 URL 更改为 [server]/auth/mycontext/access-management/admin/master/console/

我真的不明白这里发生了什么。在我的本地设置 KEYCLOAK_FRONTEND_URL 也会破坏 links.

我试过将入口的rewrite注解改成/mycontext/access-management/,但是这个配置根本不起作用。

在 Keycloak 文档 here 中,它谈到了一个名为 adminUrl 的 属性,但是,设置 -DadminUrl-Dkeycloak.adminUrl 似乎被完全忽略了根据 JBoss 文档页面使用 JAVA_OPTS_APPEND 时的 docker 图像。

我在这里错过了什么?我的配置中是否遗漏了什么?

请注意,我们别无选择,只能将其暴露在后跟名称的上下文路径下(即 /mycontext/access-management)。这是因为我们的客户需求以及我们在 /mycontext 下部署了许多微服务,每个微服务都有自己的入口配置。

感谢任何帮助。

好吧,我收集了所有提到的解决方案,成功地完成了这项工作。

所以基本上,web-context 需要设置,这是除了口耳相传之外的任何文档中都没有提到的东西。

要设置它,您可以编写 cli 脚本:

set CONTEXT=${env.KEYCLOAK_WEB_CONTEXT}
echo $CONTEXT
embed-server --server-config=standalone-ha.xml --std-out=echo
/subsystem=keycloak-server/:write-attribute(name=web-context,value=$CONTEXT)
stop-embedded-server

embed-server --server-config=standalone.xml --std-out=echo
/subsystem=keycloak-server/:write-attribute(name=web-context,value=$CONTEXT)
stop-embedded-server

这里提到了 here 但重要的是 1. 你需要启动嵌入服务器,否则没有服务器可以连接,其次你应该同时更改 standalone.xmlstandalone-ha.xml 除非你知道你到底是哪一个 运行.

查看此回答 here,了解如何将自定义脚本复制到您的 docker 图像。

不过,这里有一点很重要!尽管 Keycloak 文档说您可以将前端 URL 更改为您想要的任何内容,但实际上您必须在新 URL 的末尾添加 /auth。似乎 Keycloak 中的许多页面都被硬编码到该路径

现在您需要在 ConfigMap 中设置这两个属性:

#ConfigMap
# Has to end with /auth and has to be absolute URL
KEYCLOAK_FRONTEND_URL: https://your.website.address/mycontext/access-management/auth
PROXY_ADDRESS_FORWARDING: "true"
# The following is our own env var that will be used by the above cli
# Note that it SHOULD NOT start with / and it must END with /auth
KEYCLOAK_WEB_CONTEXT: mycontext/access-management/auth

这有点烦人,因为 KEYCLOAK_FRONTEND_URL 不能是相对路径,必须是完整的绝对路径 URL。问题是您的构建使事情变得不美观和不优雅。幸运的是,我们在 global 中有一个 host 属性 并且在 Helm 的子图表中共享,所以我可以使用它,但实际上这让设计有点讨厌。

但不仅如此,由于所有这些垃圾设置,现在您必须将 livenessreadiness 探测器更改为 GET /mycontext/access-management 更糟糕的是,如果你有微服务,这对我们来说将近 20 个,你将需要将所有以前像 http://access-management:8080/auth 一样简单的身份验证服务器 URL 更改为 http://access-management:8080/mycontext/access-management/auth.

现在请确保您的入口还包括这条新路径以及另一条重要的 属性 proxy-buffer-size。如果您没有大缓冲区大小,Keycloak 请求可能无法工作,您将收到 Bad Gateway 错误:

Path: /mycontext/access-management(/|$)(.*)
Rewrite To: /mycontext/access-management/
nginx.ingress.kubernetes.io/proxy-buffer-size: 8k 

我真的希望我们可以通过 ingress 来解决这个问题,而不必触及所有这些东西,但这似乎是不可能的。我希望 Keycloak.X 能解决所有这些糟糕的编码问题。

web-context 不再适用于 Keycloak 18.x

但您可以使用 http-relative-path 参数代替,其中包含相对于“/”的路径。

CLI:--http-relative-path

环境:KC_HTTP_RELATIVE_PATH