Skip to main content

Command Palette

Search for a command to run...

Keycloak 源码分析 - 账号拉取

Published
2 min read

Keycloak 是什么

wiki 百科

Keycloak 是一个开源软件产品,旨在为现代的应用程序和服务,提供包含身份管理和访问管理功能的单点登录工具。

所以这个工具主要是为了解决账号的同步、身份管理与统一访问下的单点登录工具。

例如你可以将 github、google、facebook 等基于 OAuth2 的账号体系,以及基于 ldap 的账号管理体系集成到 keycloak。

我们并不需要关心账号的来源,只需要与 keycloak 进行通讯,即可解决多平台下不同账号体系的登录问题。

我这下载的版本是 keycloak v12.0.1

公司产品的解决方案

事实上在公司的产品中,我们需要提供类似 keycloak 的能力给客户,但是并不能给我们提供完整的解决方案。

但是致所有要看 keycloak 的源码,主要是有几点期望。

  • 了解用户列表的拉取
    • ldap 拉取如何实现大规模用户的拉取
    • 如何合并用户

流程

Keycloak 主要做几件事

  1. 将用户拉取下来
  2. 将用户合并到系统中
  3. 将用户通过协议(例如 OAuth2)暴露出来

因为我们的业务系统中,比较比较重「用户合并」这个能力,但是目前看起来,keycloak 解决的问题跟公司的业务不是很 match。

不过还是大概将 keycloak 的源码大概看了一下。

下面会主要关注 ldap 相关的实现,之所以关注 ldap 主要是因为我们的客户群体用 ldap 的较多,其次是 ldap 的用户量通常比较多,以及具有一定的代表性。

LDAP 的用户拉取

federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/IdentityStore.java

public interface IdentityStore {

LDAPConfig getConfig();

void add(LDAPObject ldapObject);

void update(LDAPObject ldapObject);

void remove(LDAPObject ldapObject);

public void addMemberToGroup(String groupDn, String memberAttrName, String value);

public void removeMemberFromGroup(String groupDn, String memberAttrName, String value);

List fetchQueryResults(LDAPQuery LDAPQuery);

int countQueryResults(LDAPQuery LDAPQuery);

Set queryServerCapabilities();

void validatePassword(LDAPObject user, String password) throws AuthenticationException;

void updatePassword(LDAPObject user, String password, LDAPOperationDecorator passwordUpdateDecorator);

}

上面的代码删除了一些注释,ldap 的查询实现中主要实现了这个接口,诸如 拉取、验证、数量、配置等等。

具体的实现在

federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java

public class LDAPIdentityStore implements IdentityStore { // …… }

然后在 LDAPQuery 中会进一步封装调用上面的代码,

federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/query/internal/LDAPQuery.java

public class LDAPQuery implements AutoCloseable { }

当然,在往上找,就是各种工具类的封装了。

其实本身这些代码没有太多亮点,基本上都是业务上的逻辑(当然可能是我本身 java 接触不多,仅仅是 n 年前写过安卓的水平,海涵)。

用户的合并

keycloak 的用户的合并逻辑其实跟我们公司业务中的用户合并差别很大,几乎不 match……

但是还是看一下,当学习……

用户合并实现了很多的接口。

federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java

public class LDAPStorageProvider implements UserStorageProvider, CredentialInputValidator, CredentialInputUpdater.Streams, CredentialAuthentication, UserLookupProvider.Streams, UserRegistrationProvider, UserQueryProvider.Streams, ImportedUserValidation { }

federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java

public class LDAPStorageProviderFactory implements UserStorageProviderFactory, ImportSynchronization {

public SynchronizationResult sync(KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) { }

protected SynchronizationResult importLdapUsers(KeycloakSessionFactory sessionFactory, final String realmId, final ComponentModel fedModel, List ldapUsers) { }

// …… }

上面的工厂类主要就是同步并导入用户到 keycloak 中。

后话

看到 keycloak 其实有地方也挺简单直接的,比如在 ldap 不管用户量的情况下,也是直接 fetch 加载到内存中的。

在我司的业务场景中,合并还是一个比较重的操作,并没有用流式方式来合并处理这些业务,当然跟业务场景有关。

其实 java 的代码比 go 的代码好看很多啊(可能是知名项目本身的质量较高…毕竟红帽出品…),基本上看到其名字就知道其他业务功能。

我司的代码质量还有提升空间~~~

155 views

More from this blog

会有越来的多的side projects出现

什么是side project 可以理解为工作之余开发的产品,通常是收费的服务,可作为工作之外额外收入的产品。 在目前经济下行、公司开源节流(裁员)、失业率上升的大环境下,每一个程序员都应该拥有自己的side projects来对冲未来的不可靠风险。 所以side project 不仅仅是多一种「被动收入」,他也是你未来的「筹码」——工作累了,不想干了、有小孩了、买房了、家人生病了等等这些事情发生的时候,你可以「任性」一下。 而不是一些不可靠的风险出现的时候,再来提高自己的「抗风险」能力。 上面...

Jul 28, 20231 min read61

Xbox Cloud Gaming 游戏加速尝试

Xbox Cloud Gaming 游戏加速 之前有个很老的xbox游戏机,因为性能有点差劲了,所以卖了。 偶尔还是想玩玩游戏,但是老婆不让给买xbox的物理机(怀恋单身),所以含泪玩xbox cloud gaming(以下简称 xcg),xpg会员游戏还是很丰富的。 于是买了uu加速器,坦白说uu加速器不算便宜的,但是xcg在晚上高峰期,一样卡得怀疑人生,那种被马赛克糊满脸的感受,上一次这种体验还是看小姐姐的电影。 其实用uu加速器玩是ok的,就是国内的网络情况大家都知道,dddd(懂得都懂)...

Sep 5, 20221 min read258

github codespaces 在ipad上的最佳浏览器

Github Codespaces github codespaces 是github在被微软收购后,提供的一款在线web IDE,基本与vscode一致,只是运行在浏览器上而已。 而且非常土豪的提供了4核8G内存,微软就是壕。 so,通过ipad来使用codespaces就是一件比较顺其自然的事。 可是其实也没那么简单。。 IPad使用codespaces的快捷键问题 其实最大的问题就是快捷键的问题,不管你是用saferi,还是chrome,他们提供的快捷键或多或少会与你的vscode的快捷键...

Oct 8, 20211 min read59

基于binlog检查数据错误

起因 某个表的 status 「莫名其妙」变成 0 了 其实可以判断出是 status 没有被赋值,通常是结构体的 status 默认是 0 才会被插入数据库。 于是问题看起来就很简单了:只要检查相关的更新操作中的 status 字段有没有被赋值即可。 但是 这个表是用户表。 因为历史原因,源码中的更新函数很多 调用更新函数的地方也很多 无法复现该问题,测试人员也不知道做了什么操作状态变成 0 的 所以同事关注这个问题挺久了,也没看到问题原因(当然我也没看到……) 但是恰好我在做导出 bin...

Aug 5, 20212 min read61
M

Moli'blog

64 posts

曾经的少年还在吗?