Keycloak - 如何允许在不注册的情况下链接帐户
Keycloak - how to allow linking accounts without registration
我管理的 Keycloak 领域只添加了一个完全受信任的外部 IdP,旨在成为用户的默认身份验证机制。
我不想允许用户注册,即我想手动创建一个本地Keycloak用户,然后应该允许该用户link他的外部 IdP 帐户到预先存在的 Keycloak 帐户,将电子邮件地址作为通用标识符。有权访问外部 IdP 但没有现有 Keycloak 帐户的用户不应被允许连接。
我尝试了以下 First Broker Login 设置,但每当用户尝试登录时,他都会收到一条错误消息(代码:invalid_user_credentials
)。
你知道我的错误可能是什么吗?
看起来他们在 4.5.0 版中集成了此功能。
基本上您需要创建一个新流程并添加 2 个替代执行:
如果唯一则创建用户
自动 Link 经纪账户
根据这个讨论:
https://keycloak.discourse.group/t/link-idp-to-existing-user/1094/5
It’s a bug in keycloak and they seem to be a reluctant to fix it for
whatever reason. I have very few users so I solved it by manually
querying the idp for the information keycloak uses and then copying it
into the relevant fields in the UI. So there is no sign up process for
my users I just make them myself. Obviously that’s a poor solution
though, what we really need is someone to take over that PR and
persuade the maintainers to merge it.
如 this GitHub issue response the solution is to use a JavaScript authenticator 中描述的那样处理此问题。
为此,您需要执行以下操作:
在您的服务器中启用[使用 JavaScript 的自定义身份验证器[(https://www.keycloak.org/docs/latest/server_installation/#profiles) by https://Whosebug .com/a/63274532/550222creating 配置目录中的文件 profile.properties
包含以下内容:
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)
}
那么,你可以定义如下:
- 用户必须存在 -> 替代
- 自动设置现有用户 -> 备选
老实说,我对 keycloak 的自动创建行为感到惊讶。我尝试按照此处所述添加新的身份验证流程 https://www.keycloak.org/docs/latest/server_admin/index.html#automatically-link-existing-first-login-flow
我的流量:
1 - 如果唯一则创建用户 [替代]
2 - 自动 Link 经纪账户 [替代]
我的用例:验证来自 Github 的用户(Github 作为 IDP)
结果:当 github 用户使用现有“用户名”keycloak 登录时,将 github 帐户链接到我的本地用户(基于他的用户名)。我希望使用他的电子邮件而不是用户名。
根据文档:https://www.keycloak.org/docs/latest/server_admin/index.html#detect-existing-user-first-login-flow,您必须像这样创建一个新流程:
瞧瞧 :)
我管理的 Keycloak 领域只添加了一个完全受信任的外部 IdP,旨在成为用户的默认身份验证机制。
我不想允许用户注册,即我想手动创建一个本地Keycloak用户,然后应该允许该用户link他的外部 IdP 帐户到预先存在的 Keycloak 帐户,将电子邮件地址作为通用标识符。有权访问外部 IdP 但没有现有 Keycloak 帐户的用户不应被允许连接。
我尝试了以下 First Broker Login 设置,但每当用户尝试登录时,他都会收到一条错误消息(代码:invalid_user_credentials
)。
你知道我的错误可能是什么吗?
看起来他们在 4.5.0 版中集成了此功能。
基本上您需要创建一个新流程并添加 2 个替代执行:
如果唯一则创建用户
自动 Link 经纪账户
根据这个讨论:
https://keycloak.discourse.group/t/link-idp-to-existing-user/1094/5
It’s a bug in keycloak and they seem to be a reluctant to fix it for whatever reason. I have very few users so I solved it by manually querying the idp for the information keycloak uses and then copying it into the relevant fields in the UI. So there is no sign up process for my users I just make them myself. Obviously that’s a poor solution though, what we really need is someone to take over that PR and persuade the maintainers to merge it.
如 this GitHub issue response the solution is to use a JavaScript authenticator 中描述的那样处理此问题。
为此,您需要执行以下操作:
在您的服务器中启用[使用 JavaScript 的自定义身份验证器[(https://www.keycloak.org/docs/latest/server_installation/#profiles) by https://Whosebug .com/a/63274532/550222creating 配置目录中的文件
profile.properties
包含以下内容: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) }
那么,你可以定义如下:
- 用户必须存在 -> 替代
- 自动设置现有用户 -> 备选
老实说,我对 keycloak 的自动创建行为感到惊讶。我尝试按照此处所述添加新的身份验证流程 https://www.keycloak.org/docs/latest/server_admin/index.html#automatically-link-existing-first-login-flow
我的流量:
1 - 如果唯一则创建用户 [替代]
2 - 自动 Link 经纪账户 [替代]
我的用例:验证来自 Github 的用户(Github 作为 IDP)
结果:当 github 用户使用现有“用户名”keycloak 登录时,将 github 帐户链接到我的本地用户(基于他的用户名)。我希望使用他的电子邮件而不是用户名。
根据文档:https://www.keycloak.org/docs/latest/server_admin/index.html#detect-existing-user-first-login-flow,您必须像这样创建一个新流程:
瞧瞧 :)