经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
keycloak~RequiredActionProvider的使用
来源:cnblogs  作者:张占岭  时间:2024/4/11 10:43:47  对本文有异议

使用场景

RequiredActionProvider,它是在认证过程中,需要当前登录的用户执行个性化的动作;当用户符合条件,就被执行RequiredActionProvider对作,当RequiredActionProvider没有正常提交(context.success())之前,当前用户仍然是未登录状态,这在keycloak框架中,也有一些默认的个性化动作,它与整个登录流程是解耦的,事实上,keycloak的设计理念也是微架构设计,插件化设计。

keycloak默认提供的RequiredActionProvider

  • VERIFY_EMAIL 验证邮箱
  • UPDATE_PROFILE 更新用户信息
  • CONFIGURE_TOTP 配置totp多因子认证
  • UPDATE_PASSWORD 强制更新密码,用在临时建立的密码场景(CredentialRepresentation中的isTemporary为true时执行)
  • TERMS_AND_CONDITIONS 用户在首次登录时会被要求查看并接受特定的服务条款和条件
  • VERIFY_PROFILE 验证个人信息

keycloak后台配置RequiredActionProvider

在侧-验证菜单,选择Required Action标签,可以管理它们,开启或者设置成默认,同时也可以添加自定义的RequiredActionProvider

1 配置列表

2 添加新的Required Action

自定义的RequiredActionProvider

下面我们添加一个自定义的RequiredActionProvider,业务场景是,当登录用户名前缀是test时,就让这个用户去验证手机号

1 添加一个UpdatePhoneNumberRequiredAction文件,让它实现RequiredActionProvider接口

  1. public class UpdatePhoneNumberRequiredAction implements RequiredActionProvider {
  2. public static final String PROVIDER_ID = "UPDATE_PHONE_NUMBER";
  3. @Override
  4. public void evaluateTriggers(RequiredActionContext context) {
  5. }
  6. @Override
  7. public void requiredActionChallenge(RequiredActionContext context) {
  8. Response challenge = context.form()
  9. .createForm("login-update-phone-number.ftl");
  10. context.challenge(challenge);
  11. }
  12. @Override
  13. public void processAction(RequiredActionContext context) {
  14. TokenCodeServiceProvider tokenCodeServiceProvider = context.getSession().getProvider(TokenCodeServiceProvider.class);
  15. String phoneNumber = context.getHttpRequest().getDecodedFormParameters().getFirst("phoneNumber");
  16. String code = context.getHttpRequest().getDecodedFormParameters().getFirst("code");
  17. try {
  18. tokenCodeServiceProvider.validateCode(context.getUser(), phoneNumber, code);
  19. context.success();
  20. } catch (BadRequestException e) {
  21. Response challenge = context.form()
  22. .setError("noOngoingVerificationProcess")
  23. .createForm("login-update-phone-number.ftl");
  24. context.challenge(challenge);
  25. } catch (ForbiddenException e) {
  26. Response challenge = context.form()
  27. .setAttribute("phoneNumber", phoneNumber)
  28. .setError("verificationCodeDoesNotMatch")
  29. .createForm("login-update-phone-number.ftl");
  30. context.challenge(challenge);
  31. }
  32. }
  33. @Override
  34. public void close() {
  35. }
  36. }

2 添加UpdatePhoneNumberRequiredActionFactory文件,让它去构建上面的UpdatePhoneNumberRequiredAction实例

  1. public class UpdatePhoneNumberRequiredActionFactory implements RequiredActionFactory {
  2. private static final UpdatePhoneNumberRequiredAction instance = new UpdatePhoneNumberRequiredAction();
  3. @Override
  4. public String getDisplayText() {
  5. return "";
  6. }
  7. @Override
  8. public RequiredActionProvider create(KeycloakSession session) {
  9. return instance;
  10. }
  11. @Override
  12. public void init(Scope scope) {
  13. }
  14. @Override
  15. public void postInit(KeycloakSessionFactory sessionFactory) {
  16. }
  17. @Override
  18. public void close() {
  19. }
  20. @Override
  21. public String getId() {
  22. return UpdatePhoneNumberRequiredAction.PROVIDER_ID;
  23. }
  24. }

3 在resources/META-INF/services/文件夹下,添加org.keycloak.authentication.RequiredActionFactory文件,通过SPI的方式,注册咱们的UpdatePhoneNumberRequiredActionFactory工厂

  1. org.keycloak.phone.authentication.requiredactions.UpdatePhoneNumberRequiredActionFactory

4 添加咱们这个UpdatePhoneNumberRequiredActionFactory,它在keycloak后台RequiredActionProvider中,显示的名称是“Update Phone Number”,我们去添加并开启它

5 在brower的认证流程中,你需要在context.success()之前去判断用户名的前缀,并为它指定RequiredAction,如果是对所有用户有效的,那不需要添加以下代码,可以把它在keycloak后台,设置为“默认”行为即可。

  • 要想使RequiredAction生效,需要先在keycloak后台启用它
  • 要想对新建用户启用它,需要先在keycloak后台启用它,并开启“默认”选项【默认是对新用户来说的,老用户不受这个值的控制,就是说你新建一个requiredAction,没有任何规则,如果你开启+默认,那它只对所有新建用户有效】
  • 要想对某些规则的用户启用它,需要在form表单认证时,添加对应的业务逻辑,可以添加自定义的"Authenticator"来实现这个逻辑,尽量不修改之前的核心代码。
  • 当前用户执行的RequiredAction步骤,会在数据表user_required_action中存储,用户每次登录都会检查这个表的状态,如果用户存在这表里,你的对应的RequiredAction关闭了,事实上,当前这个老用户在登录时依然会走这个RequiredAction逻辑。
  • 注意,这个user_required_action表产生的数据会有缓存,只删除数据表记录是不起作用的,需要重启keycloak
  • 这个user_required_action表里对应的用户数据,当用户成功验证后,这条数据会被删除,下次用户再登录,就不会出现required_action了
  1. if(context.getUser().getUsername().startsWith("test")){
  2. context.getUser().addRequiredAction(UpdatePhoneNumberRequiredAction.PROVIDER_ID);
  3. }
  4. context.success();

好了,到目前来说,咱们用户名登录时,前缀为test的用户,都会走这个手机验证的界面了,在验证成功前,用户是不能直接登录的。

原文链接:https://www.cnblogs.com/lori/p/18128023

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号