Keycloak 自定义用户联合和身份提供者工作顺序

Posted

技术标签:

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

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

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

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

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

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

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

请分享您的经验。 谢谢

【问题讨论】:

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

【讨论】:

以上是关于Keycloak 自定义用户联合和身份提供者工作顺序的主要内容,如果未能解决你的问题,请参考以下文章

Keycloak:在社交身份提供者登录时传递自定义用户属性

是否可以在 Keycloak 中使用自定义身份验证逻辑?

是否可以在Keycloak中使用自定义身份验证逻辑?

Keycloak 用户联合提供程序模块日志记录级别

在 Keycloak SPI/Provider 中获取当前用户访问令牌(初始登录时)

如何在 Keycloak 中创建客户端以与 AWS Cognito 身份联合使用