首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >只读联邦用户的Keycloak OTP

只读联邦用户的Keycloak OTP
EN

Stack Overflow用户
提问于 2022-01-31 16:54:49
回答 2查看 1.5K关注 0票数 0

我已经实现了一个自定义用户存储提供程序,用于从我们的数据库联合用户。

我希望通过keycloak为这些用户管理OTP,当我在流中将OTP设置为required,并将OTP配置为所需的操作时,otp表单将在联合用户登录后显示,但当我试图设置OTP时,接收到的错误用户将仅为此更新读取。

如何允许只读联邦用户允许通过keycloak进行OTP配置?

代码语言:javascript
代码运行次数:0
运行
复制
2022-01-31 17:00:12,704 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-669) Uncaught server error: org.keycloak.storage.ReadOnlyException: user is read only for this update
at org.keycloak.keycloak-server-spi@15.1.1//org.keycloak.storage.adapter.AbstractUserAdapter.removeRequiredAction(AbstractUserAdapter.java:77)
at org.keycloak.keycloak-services@15.1.1//org.keycloak.services.resources.LoginActionsService.processRequireAction(LoginActionsService.java:1044)
at org.keycloak.keycloak-services@15.1.1//org.keycloak.services.resources.LoginActionsService.requiredActionPOST(LoginActionsService.java:967)

用户适配器是

代码语言:javascript
代码运行次数:0
运行
复制
public class UserAdminAdapter extends AbstractUserAdapter {
    
  private final CustomUser user;
    
  public UserAdminAdapter(
    KeycloakSession session,
    RealmModel realm,
    ComponentModel storageProviderModel,
    CustomUser user) {
        super(session, realm, storageProviderModel);
        this.user = user;
  }
    
  @Override
  public String getUsername() {
    return user.getUsername();
  }
    
  @Override
  public Stream<String> getAttributeStream(String name) {
        Map<String, List<String>> attributes = getAttributes();
        return (attributes.containsKey(name)) ? attributes.get(name).stream() : Stream.empty();
  }
    
  @Override
  protected Set<GroupModel> getGroupsInternal() {
    if (user.getGroups() != null) {
        return user.getGroups().stream().map(UserGroupModel::new).collect(Collectors.toSet());
    }
    return new HashSet<>();
  }
    
  @Override
  protected Set<RoleModel> getRoleMappingsInternal() {
    if (user.getRoles() != null) {
        return user.getRoles().stream().map(roleName -> new UserRoleModel(roleName, realm)).collect(Collectors.toSet());
    }
    return new HashSet<>();
  }
    
  @Override
  public boolean isEnabled() {
    return user.isEnabled();
  }
    
  @Override
  public String getId() {
    return StorageId.keycloakId(storageProviderModel, user.getUserId() + "");
  }
    
  @Override
  public String getFirstAttribute(String name) {
    List<String> list = getAttributes().getOrDefault(name, Collections.emptyList());
    return list.isEmpty() ? null : list.get(0);
  }
    
  @Override
  public Map<String, List<String>> getAttributes() {
    MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>();
    attributes.add(UserModel.USERNAME, getUsername());
    attributes.add(UserModel.EMAIL, getEmail());
    attributes.add(UserModel.FIRST_NAME, getFirstName());
    attributes.add(UserModel.LAST_NAME, getLastName());
    attributes.addAll(user.getAttributes());
    return attributes;
  }
    
  @Override
  public String getFirstName() {
    return user.getFirstName();
  }
    
  @Override
  public String getLastName() {
    return user.getLastName();
  }
    
  @Override
  public String getEmail() {
    return user.getEmail();
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-06 10:15:56

原因是在您的UserAdminAdapter类中,您没有实现removeRequiredActionaddRequiredAction方法。您正在接收的消息来自基类提供的默认实现。您应该自己实现这些方法,并将所需的操作存储在底层存储中,或者考虑从AbstractUserAdapterFederatedStorage扩展类,后者将所有这些功能委托给内部Keycloak实现。

票数 2
EN

Stack Overflow用户

发布于 2022-06-03 07:04:31

在我的外部DB中完全支持OTP

最后,在一个多星期后,我开始使用Keycloak 18.0。您需要做什么?简单地说,您必须实现身份验证工作流中的每一个步骤:

SPI

  • Implement

  • 创建用户存储SPI

  • 实现凭据更新SPI

  • 实现自定义凭据提供程序SPI

  • 实现自定义所需的操作SPI

  • 实现身份验证器OTP表单(我在KC中使用了OTP内部表单)H 212H 113启用所需action

  • Create浏览器工作流的副本,并在那里粘贴authenticator

这是怎么回事?

我们得到一个完全可自定义的OTP身份验证器(领域的策略pending...)

  • You可以使用该代码在您的应用程序(在db中)中进行验证)

  • ,您可以在应用程序中为OTP身份验证设置用户(不涉及KC管理页面,因此,您可以将管理页留在防火墙之外)

在我看来,这有点烦人,因为我们需要做很多循环才能在本地存储我们的数据,以及如何处理集成的OTP表单(为了“自然的外观”),但是它让我完全控制了OTP的集成,而且,我可以备份我的数据库,并且他们的OTP身份验证仍然存在,所以,如果我在KC升级失败或者它被损坏了,我仍然拥有所有的数据。

最后,下面是当您的经理具有自定义OTP身份验证时应该看到的样子

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70929788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档