Keycloak - 如何允许在没有注册的情况下链接帐户
Posted
技术标签:
【中文标题】Keycloak - 如何允许在没有注册的情况下链接帐户【英文标题】:Keycloak - how to allow linking accounts without registration 【发布时间】:2019-02-22 06:01:56 【问题描述】:我正在管理一个 Keycloak 领域,其中仅添加了一个完全受信任的外部 IdP,该 IdP 旨在成为用户的默认身份验证机制。
我确实不希望允许用户注册,即我想手动创建一个本地 Keycloak 用户,然后应该允许该用户将他的外部 IdP 帐户链接到预先存在的 Keycloak帐户,将电子邮件地址作为通用标识符。不应允许有权访问外部 IdP 但没有现有 Keycloak 帐户的用户进行连接。
我尝试了以下首次代理登录设置,但每当用户尝试登录时,他都会收到一条错误消息(代码:invalid_user_credentials
)。
你知道我的错误可能是什么吗?
【问题讨论】:
【参考方案1】:看起来他们在 4.5.0 版中集成了这个功能。
见automatic account link docs。
基本上您需要创建一个新流程并添加 2 个替代执行:
如果唯一则创建用户
自动关联代理账户
【讨论】:
在 4.5 之前的版本,比如说 3.4.3,你是如何做到这一点的? 编辑:找到答案。如果您想在 4.5.0 版本之前执行此操作,可以在此处查看:github.com/ohioit/keycloak-link-idp-with-user 我处于与原始问题类似的情况,但不幸的是,如果用户不存在,则会创建用户,但原始帖子希望没有预先存在帐户的用户无法进行身份验证. 您好@Alvaro,请问您找到解决方案了吗?仅当帐户已经存在时,我想通过链接他的 idp 帐户来登录用户。如果该帐户不在我的数据库中,则他无法登录 @hakimovic 正如我在下面发布的那样,我找到了使用自定义 javascript 身份验证器的解决方案。【参考方案2】:根据这个讨论:
https://keycloak.discourse.group/t/link-idp-to-existing-user/1094/5
这是 keycloak 中的一个错误,他们似乎不愿意修复它 不管什么原因。我的用户很少,所以我手动解决了 查询 idp 以获取 keycloak 使用的信息,然后复制它 进入 UI 中的相关字段。所以没有注册过程 我的用户我只是自己制作。显然这是一个糟糕的解决方案 不过,我们真正需要的是有人来接管那个 PR 并且 说服维护者合并它。
这是公关:https://github.com/keycloak/keycloak/pull/6282
【讨论】:
【参考方案3】:正如this GitHub issue response 中所述,解决方案是使用处理此问题的JavaScript authenticator。
为此,您需要执行以下操作:
通过 https://***.com/a/63274532/550222 在您的服务器中启用 [使用 JavaScript 的自定义身份验证器[(https://www.keycloak.org/docs/latest/server_installation/#profiles) 创建文件@ 987654324@ 在您的配置目录中,其中包含以下内容:
feature.scripts=enabled
创建自定义身份验证器。您必须创建一个具有以下结构的 JAR 文件(本质上是一个 ZIP 文件):
META-INF/keycloak-scripts.json
auth-user-must-exist.js
文件的内容在this Gist,但我也将它们包括在这里:
META-INF/keycloak-scripts.json
:
"authenticators": [
"name": "User must exists",
"fileName": "auth-user-must-exists.js",
"description": "User must exists"
]
auth-user-must-exist.js
:
AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError")
ServicesLogger = Java.type("org.keycloak.services.ServicesLogger")
AbstractIdpAuthenticator = Java.type("org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator")
IdpCreateUserIfUniqueAuthenticator = Java.type("org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator")
var IdpUserMustExists = Java.extend(IdpCreateUserIfUniqueAuthenticator)
function authenticate(context)
var auth = new IdpUserMustExists()
authenticateImpl: function(context, serializedCtx, brokerContext)
var parent = Java.super(auth)
var session = context.getSession()
var realm = context.getRealm()
var authSession = context.getAuthenticationSession()
if (authSession.getAuthNote(AbstractIdpAuthenticator.EXISTING_USER_INFO) != null)
context.attempted()
return
var username = parent.getUsername(context, serializedCtx, brokerContext)
if (username == null)
ServicesLogger.LOGGER.resetFlow(realm.isRegistrationEmailAsUsername() ? "Email" : "Username")
authSession.setAuthNote(AbstractIdpAuthenticator.ENFORCE_UPDATE_PROFILE, "true")
context.resetFlow()
return
var duplication = parent.checkExistingUser(context, username, serializedCtx, brokerContext)
if (duplication == null)
LOG.info("user not found " + username)
context.failure(AuthenticationFlowError.INVALID_USER)
return
else
authSession.setAuthNote(AbstractIdpAuthenticator.EXISTING_USER_INFO, duplication.serialize())
context.attempted()
auth.authenticate(context)
那么,你可以定义如下:
用户必须存在 -> 替代 自动设置现有用户 -> 替代【讨论】:
【参考方案4】:老实说,我对 keycloak 自动创建行为感到惊讶。我尝试添加新的身份验证流程,如此处所述https://www.keycloak.org/docs/latest/server_admin/index.html#automatically-link-existing-first-login-flow
我的流程:
1 - 如果唯一则创建用户 [ALTERNATIVE]
2 - 自动关联代理账户 [ALTERNATIVE]
我的用例:从 Github 对用户进行身份验证(Github 作为 IDP)
结果:当 github 用户使用现有的“用户名”keycloak 登录时,将 github 帐户链接到我的本地用户(基于他的用户名)。我希望使用他的电子邮件而不是用户名。
【讨论】:
【参考方案5】:根据文档:https://www.keycloak.org/docs/latest/server_admin/index.html#detect-existing-user-first-login-flow,您必须像这样创建一个新流程:
等等 :)
【讨论】:
以上是关于Keycloak - 如何允许在没有注册的情况下链接帐户的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有管理员帐户的情况下通过 REST 获取 Keycloak 用户
如何在没有登录页面的情况下将 Keycloak 与 Spring Boot(API) 集成