在反向代理后面使用 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
遗憾的是,我的问题仍然存在:
所以我现在没有想法,希望你能帮助我:
如何告诉 keycloak 在此处通过 https 调用它的 css-文件?
我是否必须更改 cli 脚本中的某些内容?
脚本内容如下:
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-For
和X-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-For
和 X-Forwarded-Proto
headers(如 Boomer 所说)并确保它们到达 Keycloak 服务器。
X-Forwarded-For
应该是路由到 LB 的 Keycloak 域,X-Forwarded-Proto
应该是协议(大多数情况下是 https)。
作为最后一步,您需要修改 standalone.xml
或 standalone-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-For
、X-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
所以我在让 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
遗憾的是,我的问题仍然存在:
所以我现在没有想法,希望你能帮助我:
如何告诉 keycloak 在此处通过 https 调用它的 css-文件?
我是否必须更改 cli 脚本中的某些内容?
脚本内容如下:
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-For
和X-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-For
和 X-Forwarded-Proto
headers(如 Boomer 所说)并确保它们到达 Keycloak 服务器。
X-Forwarded-For
应该是路由到 LB 的 Keycloak 域,X-Forwarded-Proto
应该是协议(大多数情况下是 https)。
作为最后一步,您需要修改 standalone.xml
或 standalone-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=true2。您应该为 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-For
、X-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