Keycloak:实现“重置密码”(作为管理员)流程与“忘记密码”(作为用户)相同
Posted
技术标签:
【中文标题】Keycloak:实现“重置密码”(作为管理员)流程与“忘记密码”(作为用户)相同【英文标题】:Keycloak : implement "reset password" (as admin) flow same as "forgot password" (as user) 【发布时间】:2021-06-25 22:08:19 【问题描述】:我想在 Keycloak 中实现这个身份验证流程:
-
用户仅通过输入电子邮件来创建帐户
用户已登录并可以访问我的服务
2'。同时,会向他发送一封电子邮件,让他“完成”他的帐户
用户离开他的会话 -> 要重新使用我的服务,他必须点击收到的电子邮件
通过点击收到的电子邮件,用户定义了他的第一个密码
然后用户会自动登录(无需通过登录页面)。
此流程的目标是最简单的,以吸引不习惯 web 应用的用户。
我会做的实现:
创建一个无需密码请求的帐户:我通过禁用 Password Validation
和Profile Validation
规则来自定义 Keycloak Registration
流程
以编程方式,在我的 web 应用程序中,在用户第一次连接时,通过 REST 管理 API,我触发电子邮件操作 UPDATE_PASSWORD
我得到了一些有用的东西,但是:
A.通过电子邮件收到的链接重定向到确认执行操作的中间页面(“执行以下操作”)-(类似于Keycloak Implement Reset password flow same as forgot password flow)
B.然后用户被重定向到登录页面,而不是直接连接到应用程序。
当我作为普通用户触发重置密码请求(通过“忘记密码”功能)时,该过程就是我想要的:通过单击电子邮件链接,我直接进入允许我输入的页面并确认新密码,然后我就通过了身份验证。
我的问题:您是否看到了实现这种“简化”流程的方法?
我的 keycloak 版本:11.0.2
谢谢!
【问题讨论】:
【参考方案1】:我可以删除“info.ftl”页面显示,自定义“ExecuteActionsActionTokenHandler”,如下所述:
action-token-spi
你必须创建一个文件:
src/main/resources/META-INF/services/org.keycloak.authentication.actiontoken.ActionTokenHandlerFactory
包含您要使用的类的名称:
com.example.ExecuteActionTokenHandlerFactory
然后您使用以下代码创建该类 com.example.ExecuteActionTokenHandlerFactory:
public class ExecuteActionTokenHandlerFactory extends ExecuteActionsActionTokenHandler
@Override
public Response handleToken(ExecuteActionsActionToken token, ActionTokenContext<ExecuteActionsActionToken> tokenContext)
AuthenticationSessionModel authSession = tokenContext.getAuthenticationSession();
String redirectUri = RedirectUtils.verifyRedirectUri(tokenContext.getUriInfo(), token.getRedirectUri(),
tokenContext.getRealm(), authSession.getClient());
if (redirectUri != null)
authSession.setAuthNote(AuthenticationManager.SET_REDIRECT_URI_AFTER_REQUIRED_ACTIONS, "true");
authSession.setRedirectUri(redirectUri);
authSession.setClientNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUri);
token.getRequiredActions().stream().forEach(authSession::addRequiredAction);
UserModel user = tokenContext.getAuthenticationSession().getAuthenticatedUser();
// verify user email as we know it is valid as this entry point would never have gotten here.
user.setEmailVerified(true);
String nextAction = AuthenticationManager.nextRequiredAction(tokenContext.getSession(), authSession, tokenContext.getClientConnection(), tokenContext.getRequest(), tokenContext.getUriInfo(), tokenContext.getEvent());
return AuthenticationManager.redirectToRequiredActions(tokenContext.getSession(), tokenContext.getRealm(), authSession, tokenContext.getUriInfo(), nextAction);
其实和上层的实现是一样的,只是我们去掉了以下部分:
if (tokenContext.isAuthenticationSessionFresh())
...
这意味着如果用户没有会话,当用户重置他的密码时,他会被重定向到那个“info.ftl”页面。
【讨论】:
【参考方案2】:作为问题 A 的解决方法,我自定义了info.ftl
模板页面。我在链接上向click
添加了一个丑陋的内联脚本,自动重定向到更新密码页面。
<#import "template.ftl" as layout>
(...)
<#elseif actionUri?has_content>
<p><a id="yolo" href="$actionUri">$kcSanitize(msg("proceedWithAction"))?no_esc</a></p>
<script>document.getElementById('yolo').click()</script>
(...)
在我找到更清洁的解决方案之前,它会完成这项工作。
目前,B问题依然存在。
【讨论】:
以上是关于Keycloak:实现“重置密码”(作为管理员)流程与“忘记密码”(作为用户)相同的主要内容,如果未能解决你的问题,请参考以下文章