配置主机名 (v2)

了解如何配置 Keycloak 公开的前端和后通道端点。

设置主机名选项的重要性

默认情况下,Keycloak 强制配置 hostname 选项,并且不会动态解析 URL。 这是一项安全措施。

Keycloak 自由地公开其自身的 URL,例如通过 OIDC Discovery 端点,或者作为电子邮件中密码重置链接的一部分。 如果主机名是从主机名标头动态解释的,则可能会为潜在的攻击者提供机会来操纵电子邮件中的 URL,将用户重定向到攻击者的虚假域,并窃取敏感数据,例如操作令牌、密码等。

通过显式设置 hostname 选项,我们避免了令牌可能由欺诈性颁发者颁发的情况。 可以使用以下命令以显式主机名启动服务器

bin/kc.[sh|bat] start --hostname my.keycloak.org
这些示例以生产模式启动 Keycloak 实例,这需要公共证书和私钥才能保护通信安全。 有关更多信息,请参阅配置 Keycloak 以进行生产

定义主机名选项的特定部分

如前面的示例所示,方案和端口不是显式必需的。 在这种情况下,Keycloak 会自动处理这些方面。 例如,在给定的示例中,服务器可以通过 https://my.keycloak.org:8443 访问。 但是,反向代理通常会在默认端口(例如 443)上公开 Keycloak。 在这种情况下,最好在 hostname 选项中指定完整的 URL,而不是保持 URL 部分动态。 然后可以使用以下命令启动服务器

bin/kc.[sh|bat] start --hostname https://my.keycloak.org

同样,您的反向代理可能会在不同的上下文路径下公开 Keycloak。 可以配置 Keycloak 以通过 hostnamehostname-admin 选项反映这一点。 请参阅以下示例

bin/kc.[sh|bat] start --hostname https://my.keycloak.org:123/auth

利用内部 URL 进行客户端之间的通信

Keycloak 能够为后通道请求提供单独的 URL,从而在保持使用公共 URL 进行前通道请求的同时,实现内部通信。 此外,后通道会根据传入的标头动态解析。 考虑以下示例

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --hostname-backchannel-dynamic true

通过这种方式,您的应用程序(称为客户端)可以通过本地网络连接到 Keycloak,而服务器在 https://my.keycloak.org 仍然可以公开访问。

使用边缘 TLS 终止

您可以看到,HTTPS 协议是默认选择,这符合 Keycloak 对安全最佳实践的承诺。 但是,Keycloak 也为用户提供了在必要时选择 HTTP 的灵活性。 这可以通过简单地指定 HTTP 侦听器来实现,有关详细信息,请查阅配置 TLS。 使用边缘 TLS 终止代理,您可以按如下方式启动服务器

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --http-enabled true

此配置的结果是,您可以通过 HTTPS 继续在 https://my.keycloak.org 访问 Keycloak,而代理使用 HTTP 和端口 8080 与实例交互。

使用反向代理

当代理转发 http 或重新加密的 TLS 请求时,应设置 proxy-headers 选项。 根据主机名设置,URL 的某些或全部可能被动态确定。

如果选择 forwardedxforwarded,请确保您的反向代理正确设置并覆盖 ForwardedX-Forwarded-* 标头。 要设置这些标头,请查阅您的反向代理的文档。 错误配置将使 Keycloak 暴露于安全漏洞。

完全动态的 URL

例如,如果您的反向代理正确设置了 Forwarded 标头,并且您不想硬编码主机名,Keycloak 可以适应这一点。 您只需按如下方式启动服务器即可

bin/kc.[sh|bat] start --hostname-strict false --proxy-headers forwarded

通过此配置,服务器会遵守 Forwarded 标头设置的值。 这也意味着所有端点都是动态解析的。

部分动态 URL

hostname 选项未指定为完整 URL 时,proxy-headers 选项也可以用于部分动态地解析 URL。 例如

bin/kc.[sh|bat] start --hostname my.keycloak.org --proxy-headers xforwarded

在这种情况下,方案和端口从 X-Forwarded-* 标头动态解析,而主机名静态定义为 my.keycloak.org

固定 URL

即使 hostname 设置为完整 URL,proxy-headers 仍然相关,因为标头用于确定请求的来源。 例如

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --proxy-headers xforwarded

在这种情况下,虽然没有任何内容从 X-Forwarded-* 标头动态解析,但 X-Forwarded-* 标头用于确定请求的正确来源。

在单独的主机名上公开管理控制台

如果您希望在不同的主机上公开管理控制台,可以使用以下命令执行此操作

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --hostname-admin https://admin.my.keycloak.org:8443

这允许您在 https://my.keycloak.org 访问 Keycloak,并在 https://admin.my.keycloak.org:8443 访问管理控制台,而后端继续使用 https://my.keycloak.org

请记住,主机名和代理选项不会更改服务器侦听的端口。 相反,它仅更改静态资源的端口,如 JavaScript 和 CSS 链接、OIDC 众所周知的端点、重定向 URI 等,这些资源将在代理前面使用。 您需要使用 HTTP 配置选项来更改服务器正在侦听的实际端口。 有关详细信息,请参阅所有配置
使用 hostname-admin 选项不会阻止通过 hostname 选项指定的前端 URL 访问管理 REST API 端点。 如果您想限制对管理 REST API 的访问,则需要在反向代理级别执行此操作。 管理控制台隐式使用 hostname-admin 选项指定的 URL 访问 API。

背景 - 服务器端点

Keycloak 公开了多个端点,每个端点都有不同的用途。 它们通常用于应用程序之间的通信或用于管理服务器。 我们识别出 3 个主要端点组

  • 前端

  • 后端

  • 管理

如果您想使用这些端点中的任何一个,您需要设置基本 URL。 基本 URL 由几个部分组成

  • 方案(例如 https 协议)

  • 主机名(例如 example.keycloak.org)

  • 端口(例如 8443)

  • 路径(例如 /auth)

每个组的基本 URL 对令牌的颁发和验证方式、为需要用户重定向到 Keycloak 的操作创建链接的方式(例如,通过电子邮件链接重置密码时),以及最重要的是,应用程序在从 realms/{realm-name}/.well-known/openid-configuration 获取 OpenID Connect Discovery 文档时如何发现这些端点,都具有重要影响。

前端

用户和应用程序使用前端 URL 通过前通道访问 Keycloak。 前通道是可公开访问的通信通道。 例如,基于浏览器的流程(访问登录页面、单击链接以重置密码或绑定令牌)可以被视为前通道请求。

为了使 Keycloak 可通过前端 URL 访问,您需要设置 hostname 选项

bin/kc.[sh|bat] start --hostname my.keycloak.org

后端

后端端点是通过公共域或私有网络访问的端点。 它们与 Keycloak 和客户端(由 Keycloak 保护的应用程序)之间的直接后端通信有关。 这种通信可能通过本地网络进行,避免了反向代理。 属于此组的端点的示例包括授权端点、令牌和令牌内省端点、userinfo 端点、JWKS URI 端点等。

hostname-backchannel-dynamic 选项的默认值为 false,这意味着后通道 URL 与前通道 URL 相同。 可以通过设置以下选项来启用从传入请求标头动态解析后通道 URL

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --hostname-backchannel-dynamic true

请注意,hostname 选项必须设置为 URL。 有关更多信息,请参阅下面的验证部分。

管理

与基本前端 URL 类似,您还可以为管理控制台的资源和端点设置基本 URL。 服务器使用特定 URL 公开管理控制台和静态资源。 此 URL 用于重定向 URL、加载资源(CSS、JS)、管理 REST API 等。 这可以通过设置 hostname-admin 选项来完成

bin/kc.[sh|bat] start --hostname https://my.keycloak.org --hostname-admin https://admin.my.keycloak.org:8443

同样,hostname 选项必须设置为 URL。 有关更多信息,请参阅下面的验证部分。

解析 URL 的来源

如前几节所示,URL 可以通过多种方式解析:它们可以是动态生成的、硬编码的,或者是两者的组合

  • 从传入请求动态

    • 主机标头、方案、服务器端口、上下文路径

    • 代理设置的标头:ForwardedX-Forwarded-*

  • 硬编码

    • 服务器范围配置(例如 hostnamehostname-admin 等)

    • 前端 URL 的领域配置

验证

  • hostname URL 和 hostname-admin URL 经过验证,使用了完整的 URL,包括方案和主机名。 仅当存在端口时才验证端口,否则假定给定协议的默认端口(80 或 443)。

  • 在生产配置文件 (kc.sh|bat start) 中,必须显式配置 --hostname--hostname-strict false

    • 这不适用于开发配置文件 (kc.sh|bat start-dev),其中 --hostname-strict false 是默认值。

  • 如果未配置 --hostname

    • hostname-backchannel-dynamic 必须设置为 false。

    • hostname-strict 必须设置为 false。

  • 如果配置了 hostname-admin,则 hostname 必须设置为 URL(不仅仅是主机名)。 否则,当访问管理控制台时,Keycloak 将不知道正确的前端 URL(包括端口等)。

  • 如果 hostname-backchannel-dynamic 设置为 true,则 hostname 必须设置为 URL(不仅仅是主机名)。 否则,当通过动态解析的后通道访问时,Keycloak 将不知道正确的前端 URL(包括端口等)。

此外,如果配置了主机名,则忽略 hostname-strict。

故障排除

要对主机名配置进行故障排除,您可以使用专用调试工具,可以通过以下方式启用该工具

Keycloak 配置
bin/kc.[sh|bat] start --hostname=mykeycloak --hostname-debug=true

Keycloak 正确启动后,打开浏览器并转到: http://mykeycloak:8080/realms/<your-realm>/hostname-debug

相关选项

表 1. 默认情况下,此端点已禁用 (--hostname-debug=false)

hostname

服务器公开的地址。

可以是完整 URL,也可以仅是主机名。 当仅提供主机名时,方案、端口和上下文路径将从请求中解析。

CLI: --hostname
Env: KC_HOSTNAME

仅当启用 hostname:v2 功能时可用

hostname-admin

用于访问管理控制台的地址。

如果您使用与 hostname 选项中指定的地址不同的地址上的反向代理公开管理控制台,请使用此选项。

CLI: --hostname-admin
Env: KC_HOSTNAME_ADMIN

仅当启用 hostname:v2 功能时可用

hostname-backchannel-dynamic

启用动态解析后通道 URL,包括主机名、方案、端口和上下文路径。

如果您的应用程序通过专用网络访问 Keycloak,请设置为 true。 如果设置为 true,则需要将 hostname 选项指定为完整 URL。

CLI: --hostname-backchannel-dynamic
Env: KC_HOSTNAME_BACKCHANNEL_DYNAMIC

仅当启用 hostname:v2 功能时可用

true, false (默认)

hostname-debug

切换主机名调试页面,该页面可在 /realms/master/hostname-debug 访问。

CLI: --hostname-debug
Env: KC_HOSTNAME_DEBUG

仅当启用 hostname:v2 功能时可用

true, false (默认)

hostname-strict

禁用从请求标头动态解析主机名。

在生产环境中应始终设置为 true,除非您的反向代理覆盖 Host 标头。 如果启用,则需要指定 hostname 选项。

CLI: --hostname-strict
Env: KC_HOSTNAME_STRICT

仅当启用 hostname:v2 功能时可用

true (默认), false

在此页上