keycloak - 基于用户名(电子邮件地址)的领域解析

keycloak - realm resolution based on username (email address)

我正在开发一个多租户项目,其中用户名实际上是他们的电子邮件地址,电子邮件的域用作租户标识符。

现在在 keycloak 中,每个租户都有不同的领域,但我希望所有租户都有一个登录页面,而实际的领域将进行身份验证,以某种方式由用户名(电子邮件地址)解析。

我该怎么做?

我在邮件列表中发现了一个讨论相同问题的线程(我现在找不到了...)。它类似于 - 创建一个主领域,将 "proxy" 提供给其他领域,但我不太确定该怎么做。

邮件列表中的

The idea 是编写一个服务(比如说 auth-redirector.example.com),它有一个电子邮件输入字段,根据域查找领域并重定向到该领域的 keycloak 端点(例如 auth.example.com/auth/realms/realm-name/etc…) 同时保留所有 GET 参数。

您可以在此处找到直接 login/registration URL 的示例:https://lists.jboss.org/pipermail/keycloak-user/2016-July/007045.html

一个可用性问题是用户必须提供两次电子邮件,我还没有找到通过登录传递用户名的方法URL。

我认为 Michał Łazowik 的回答是正确的,但要 Single-Sign-On 起作用,需要稍微扩展一下。

请记住,由于 KEYCLOAK-4593 如果我们有 > 100 个领域,我们可能还必须有多个 Keycloak 服务器。

我们需要:

  • 专门用于此目的的单独 HTTP 服务器,auth-redirector.example.com
  • 根据用户名(电子邮件地址)确定 Keycloak 服务器和领域的算法。

下面是整个 OAuth2 授权代码流程:

一个应用程序发现用户想要登录。在多个领域之前,领域的名称将是一个常量,因此应用程序将重定向到:

https://keycloak.example.com/auth/realms/realname/protocol/openid-connect/auth?$get_params

而是重定向到

https://auth-redirector.example.com/?$get_params

auth-redirector 确定它本身是否具有此会话的有效访问令牌,可能必须先从颁发它的 Keycloak 服务器刷新访问令牌(用户可能已经注销并正在尝试登录作为不同领域服务的不同用户)。

如果它一个有效的访问令牌,我们可以根据访问令牌中的用户名或电子邮件地址确定Keycloak服务器和领域,并重定向到:

https://$keycloak_server/auth/$realm/realname/protocol/openid-connect/auth?$get_params

从这里开始,OAuth2 授权代码流程照常进行。

否则,如果 没有有效的访问令牌,auth-redirector 会将原始应用程序的 $get_params 存储为会话数据。它向用户呈现一个表单,要求输入用户名。当用户提交时,我们可以确定要使用的 Keycloak 服务器和领域,然后 auth-redirector 本身 使用自己的 $get_params 登录到 Keycloak 服务器。一旦 auth-redirector 获得 call-back,它就会从 Keycloak 服务器检索访问+刷新令牌并将它们存储在会话数据中。然后,最后,它重定向回与调用者原始 $get_params(来自会话数据)相同的 keycloak 服务器和领域。 OAuth2 授权代码流程照常进行。

这绝对是一个黑客!但我认为它可以工作。如果时间允许,我很乐意有一天尝试一下。

其他 OAuth2 流程需要其他 hacks/solutions...