【问题标题】:Keycloak Custom User Federation and Identity Provider Working OrderKeycloak 自定义用户联合和身份提供者工作顺序
【发布时间】:2018-09-09 14:40:17
【问题描述】:

我在 Keycloak 上有 两种 自定义身份验证方法。

其中之一是自定义实施的用户联合。我为 X 领域 配置了它。系统使用此实现使用用户名/密码方法登录。此实现调用我的联合服务并验证发送的用户。 它成功运行并验证联合用户。

第二个是身份代理(openid connect)。我为 Y 领域 配置了一个自定义 openid 提供程序。 它成功运行并验证提供商的用户。

我将它们都配置为相同的领域。当我尝试使用自定义身份提供程序登录时,身份验证流程正常工作。在流程结束时,配置的用户联合(自定义实现的用户联合)使用来自身份代理(自定义身份提供者)登录过程的用户名触发,并再次调用我的联合服务。

当我尝试使用身份提供者登录时,我希望用户联合(自定义实现的用户联合)工作。只有当我尝试使用用户名/密码登录时它才能工作。

如何在这种情况下阻止用户联盟的工作?

请分享您的经验。 谢谢

【问题讨论】:

  • 你找到答案了吗?
  • @Ehsan 对我迟到的回答感到抱歉。是的,我应用了一种解决方案。我创建了一个流程。 (放置在 Authentication/Flows 菜单下)。它仅包含一种身份验证类型。 (如果唯一则创建用户(创建唯一用户配置)=> 作为替代)。之后,我将此流程与我的自定义身份提供者相关联。 (您需要打开身份提供者菜单并选择您的身份提供者设置。并且您需要为“首次登录流程”下拉菜单选择创建的流程)。之后,我阻止了用户联盟在这种情况下的工作。我希望这个过程可以帮助你。

标签: authentication jboss single-sign-on keycloak jboss-tools


【解决方案1】:

我遇到了身份提供者和自定义用户联合不能同时工作的相同问题。我的解决方案不是阻止用户联合,而是更改我的自定义用户联合代码。从 UserLookupProvider 接口 (getUserByEmail/Username/Id) 返回用户的方法的实现必须编码为返回 AbstractUserAdapterFederatedStorage。 UserModel 的这种实现为 keycloak 所需的方法提供了实现,以将用户从身份提供者内部化。此外,我还实现了 UserQueryProvider 接口以及 UserStorageProvider、UserLookupProvider、CredentialInputValidator,以便能够从 keycloak 管理控制台查看这些用户。

从他们的文档中: Keycloak 附带一个帮助类 org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage,它将把除获取/设置用户名之外的每个 UserModel 方法委托给用户联合存储。

...接口 UserQueryProvider。如果您不实现此接口,则用户将无法在管理控制台中查看。不过你仍然可以登录。

参考:https://www.keycloak.org/docs/latest/server_development/#_user-storage-spi

代码: 注意:自定义 keycloak 用户存储应该至少有两个类。一个主要的任务是完成必须至少实现 UserStorageProvider 的繁重工作。另一个是调用这个类的工厂。有关此内容的更多信息,请参阅他们的服务器开发指南。以下代码进入主类(不是工厂):

@Override
    public UserModel getUserByUsername(String username, RealmModel realm) {

        [...]

            userModel = createUserModel(username, realm);

        [...]

        return userModel;
    }

protected UserModel createUserModel( String username, RealmModel realm) {
        return new AbstractUserAdapterFederatedStorage(session, realm, model) {
            @Override
            public String getUsername() {
                return username;
            }

            @Override
            public void setUsername(String username) {
//retrieves user through repository and sets the keycloak user to its username. (Seems redundant but works!)
                usersService.getUserDetails(username).setUsername(username);
                }
            };
        }

【讨论】:

    猜你喜欢
    • 2021-04-26
    • 2018-03-17
    • 1970-01-01
    • 2021-05-06
    • 2021-08-11
    • 2013-02-09
    • 2015-03-20
    • 2013-10-23
    • 2021-12-14
    相关资源
    最近更新 更多