在反向代理后面使用 Keycloak:无法打开管理员登录页面,因为混合内容

Using Keycloak behind a reverse proxy: Could not open Admin loginpage because mixed Content

所以我在让 keycloak 3.2.1 在 kong (0.10.3) 后面工作时遇到问题,kong (0.10.3) 是一个基于 nginx 的反向代理。

场景是:

我通过 https://{gateway}/auth 通过我的网关路由调用 keycloak,它向我显示了带有 keycloak 徽标的入口点,link 到管理控制台等 - 到目前为止一切顺利。

但是当单击管理控制台 -> 调用 https://{gateway}/auth/admin/master/console/ 时,keycloak 会尝试通过 http 加载它的 css/js(见下面的屏幕截图),我的浏览器会阻止它,因为混合内容。

我四处搜索并找到了这个帖子:keycloak apache server configuration with 'Mixed Content' problems which lead to this github repo: https://github.com/dukecon/keycloak_postgres_https

从那时起,我尝试将它的 cli 成功集成到我的 dockerfile 中(没有更改文件的内容,只是将它们复制到我的 repo 中,然后 add/run 从 dockerfile 中复制它们)。这是我现在的 dockerfile:

FROM jboss/keycloak-postgres:3.2.1.Final

USER root

ADD config.sh /tmp/
ADD batch.cli /tmp/

RUN bash /tmp/config.sh

#Give correct permissions when used in an OpenShift environment.
RUN chown -R jboss:0 $JBOSS_HOME/standalone && \
    chmod -R g+rw $JBOSS_HOME/standalone

USER jboss
EXPOSE 8080

遗憾的是,我的问题仍然存在:

所以我现在没有想法,希望你能帮助我:

脚本内容如下:

config.sh:

#!/bin/bash -x

set -e

JBOSS_HOME=/opt/jboss/keycloak
JBOSS_CLI=$JBOSS_HOME/bin/jboss-cli.sh
JBOSS_MODE=${1:-"standalone"}
JBOSS_CONFIG=${2:-"$JBOSS_MODE.xml"}

echo "==> Executing..."
cd /tmp

$JBOSS_CLI --file=`dirname "[=11=]"`/batch.cli

# cf. 
/bin/rm -rf ${JBOSS_HOME}/${JBOSS_MODE}/configuration/${JBOSS_MODE}_xml_history/current

和batch.cli:

embed-server --std-out=echo

# http://keycloak.github.io/docs/userguide/keycloak-server/html/server-installation.html
# 3.2.7.2. Enable SSL on a Reverse Proxy
# First add proxy-address-forwarding and redirect-socket to the http-listener element.
# Then add a new socket-binding element to the socket-binding-group element.

batch

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https)

/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)

run-batch

stop-embedded-server

可能也很有趣,kong 部署在 openshift 上,路由使用从 http 到 https 的重定向("insecureEdgeTerminationPolicy":"Redirect")。

这听起来有点像 Keycloak Docker behind loadbalancer with https fails

的重复

nginx中设置请求headersX-Forwarded-ForX-Forwarded-Proto。然后你必须配置 Keycloak(Wildfly,Undertow)与 SSL 终止反向代理(又名负载平衡器)一起工作。有关详细说明,请参阅 http://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy

重点是 nginx 正在终止 SSL 并将请求转发到 Keycloak 作为纯 http。因此必须告知 Keycloak/Wildfly 来自 nginx 的传入 http 请求必须像这样处理他们是 https.

在所有上游负载均衡器中添加 X-Forwarded-ForX-Forwarded-Proto headers(如 Boomer 所说)并确保它们到达 Keycloak 服务器。 X-Forwarded-For 应该是路由到 LB 的 Keycloak 域,X-Forwarded-Proto 应该是协议(大多数情况下是 https)。

作为最后一步,您需要修改 standalone.xmlstandalone-ha.xml 文件并将 proxy-address-forwarding="true" 属性添加到 <server> 下的 <http-listener> 元素。

如果您正在使用 Docker,您可以使用来自原始 Keycloak 容器的 PROXY_ADDRESS_FORWARDING 环境变量来设置此属性。

我和你有同样的问题,现在解决了,这是我的方法。

首先,我在一个干净的环境中使用 cloak 设置了反向代理,确认代理和 cloak 配置正确。

接下来,通过测试和猜测,我发现在设置 keycloak 时使用了从 dockerhub 和 docker 中提取的图像。和服务器端的binary设置有一些区别,从standalone.xml开始,你会发现关键点是这个2:

1.您应该为 docker env.

设置 PROXY_ADDRESS_FORWARDING=true

2。您应该为 docker env.

设置 jboss.https.port 443

如果您的 standalone.xml 也配置正确,您将在管理页面中使用它。 祝你好运 ;)

详细说明@MattBianco 的回复。在现代 Keycloak 变量中,您需要将 KEYCLOAK_FRONTEND_URL 设置为 https:///auth。使用 docker 您可以将其设置为环境变量,例如KEYCLOAK_FRONTEND_URL=https://auth.foo.com/auth

如果您使用的是 Keycloak.X(Keycloak 的 Quarkus 版本),那么这些解决方案将不起作用。

您必须设置环境变量 KC_PROXY=edge(根据 https://github.com/keycloak/keycloak-community/blob/master/design/keycloak.x/configuration.md)。

两个提示:

如果您使用 docker-compose.yml,请将以下环境变量添加到 keycloak 容器中:

environment:
  PROXY_ADDRESS_FORWARDING: "true"

重启stack,检查变量是否存在(有时候容器要重启几次)

docker-compose exec keycloak bash -c 'echo $PROXY_ADDRESS_FORWARDING'

如果您使用 Apache 容器作为代理(使用 mod_proxy),您应该手动添加 X-Forwarded-Proto 和 X-Forwarded-Port headers:

<IfModule mod_ssl.c>

# Proxy pass for keycloak
<VirtualHost *:443>
    ServerName auth.myproject_url.tld
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/certs/apache-selfsigned.key
    <IfModule mod_proxy.c>
        SSLProxyEngine on
        <Location "/">
            ProxyPass  "http://keycloak:8080/"
            ProxyPassReverse "http://keycloak:8080/"
            RequestHeader set X-Forwarded-Proto "https"
            RequestHeader set X-Forwarded-Port "443"
            #  ProxyPreserveHost On
        </Location>
    </IfModule>
    </IfModule>
</VirtualHost>

经过一番努力,我找到了使用 X-Forwarded-Host 以及其他 header 的替代解决方案。这是无证的,但它有效,而且似乎很久以前就开始工作了。检查此拉取请求 https://github.com/wildfly/wildfly/pull/5593

https://www.keycloak.org/docs/latest/server_installation 处的 Keycloak 文档提到,对于代理转发,您需要将 PROXY_ADDRESS_FORWARDING=true 设置为 docker arg 加上 X-Forwarded-ForX-Forwarded-Proto 和原始Host(在我的例子中是面向互联网的代理主机)。

但在我的情况下无法设置原始 Host,因为我在 Azure 应用服务中托管 Keycloak。实际上,主要问题是它不起作用,因为代理使用内部密钥斗篷 Host header 发送请求,这是在我的情况下唯一可行的方法。

Azure 应用程序网关正在使用 X-ORIGINAL-HOST,但 X-Forwarded-Host 似乎更广泛地用于 header 作为原始主机名。我已经尝试在我的代理上设置 X-Forwarded-Host 并且最终成功了,尽管文档中没有提到这种方法。另请查看此讨论 https://keycloak.discourse.group/t/x-forwarded-host-proxy-header-support/10730