6.9. 导入实现策略
在实施用户存储供应商时,您可以采用另一个策略。除了使用用户联邦存储外,您可以在红帽构建的 Keycloak 内置用户数据库中在本地创建用户,并将外部存储的属性复制到这个本地副本。此方法有很多优点。
- 红帽构建的 Keycloak 基本上成为外部存储的持久性用户缓存。导入用户后,您将不再到达外部存储,从而关闭它。
- 如果您要以您的官方用户存储的形式迁移到红帽 Keycloak,并弃用旧的外部存储,您可以缓慢迁移应用程序以使用红帽构建的 Keycloak。当所有应用程序都迁移后,取消链接导入的用户,然后停用旧的传统外部存储。
使用导入策略有一些明显的缺点:
- 第一次查找用户将需要对红帽构建的 Keycloak 数据库进行多次更新。这可能会因为负载造成大量性能损失,并在红帽构建的 Keycloak 数据库上造成大量压力。用户联邦存储方法仅根据需要存储额外的数据,并且永远不会根据外部存储的功能使用。
- 通过导入方法,您必须保持本地红帽构建的 Keycloak 存储和外部存储同步。User Storage SPI 具有可以实施以支持同步的功能接口,但这可能会很快变得困难且混乱。
要实现导入策略,只需首先检查用户是否已在本地导入。如果返回本地用户,如果没有在本地创建用户并从外部存储导入数据。您还可以代理本地用户,以便大多数更改会自动同步。
这将是一个点子,但我们可以扩展我们的 PropertyFileUserStorageProvider
以采用这种方法。首先修改 createAdapter ()
方法。
PropertyFileUserStorageProvider
在这个方法中,我们调用 UserStoragePrivateUtil.userLocalStorage (session)
方法来获取对本地红帽构建的 Keycloak 用户存储的引用。我们会发现用户是否存储在本地(如果不是),我们将其添加到本地。不要设置本地用户的 id
。让红帽构建的 Keycloak 会自动生成 id
。另请注意,我们调用 UserModel.setFederationLink ()
,并传递供应商 组件
模型的 ID。这将设置提供程序和导入用户之间的链接。
删除用户存储提供程序时,由它导入的任何用户也会被删除。这是调用 UserModel.setFederationLink ()
的一种目的。
要注意的是,如果本地用户链接,您的存储提供程序仍然被委派给,它从 CredentialInputValidator
和 CredentialInputUpdater
接口实现的方法。从验证或更新中返回 false
会导致红帽构建的 Keycloak 查看是否使用本地存储验证或更新。
另请注意,我们使用 org.keycloak.models.utils.UserModelDelegate
类代理本地用户。此类是 UserModel
的实现。每个方法只是委托给它所实例化的 UserModel
。我们覆盖此委派类的 setUsername ()
方法,以自动与属性文件同步。对于您的供应商,您可以使用它来 截获 本地 UserModel
上的其他方法,以与外部存储执行同步。例如,get 方法可以确保本地存储保持同步。设置方法会使外部存储与本地存储保持同步。要注意的一件事是 getId ()
方法应始终返回您在本地创建用户时自动生成的 id。您不应该返回联邦 id,如其他非导入示例所示。
如果您的供应商正在实现 UserRegistrationProvider
接口,则您的 removeUser ()
方法不需要从本地存储中删除该用户。运行时将自动执行此操作。另请注意,在从本地存储中删除之前,将调用 removeUser ()
。
6.9.1. ImportedUserValidation 接口 复制链接链接已复制到粘贴板!
如果您在本章前面文中记住,我们将讨论查询用户如何工作。如果用户找到,则首先查询本地存储,则查询结束。因为我们需要代理本地用户 Model
,因此我们可以使用户名保持同步。当链接的本地用户从本地数据库加载时,User Storage SPI 有一个回调。
每当加载链接的本地用户时,如果用户存储供应商类实现了这个接口,则调用 validate ()
方法。在这里,您可以代理作为参数传递的本地用户,并返回它。将使用新的 UserModel
。您还可以选择进行检查来查看用户是否仍然存在于外部存储中。如果 validate ()
返回 null
,则将从数据库中删除本地用户。
6.9.2. ImportSynchronization 接口 复制链接链接已复制到粘贴板!
通过导入策略,您可以看到本地用户副本可以与外部存储不同步。例如,用户可能已从外部存储中删除。User Storage SPI 有一个额外的接口来处理这个、org.keycloak.storage.user.ImportSynchronization
:
这个接口由供应商工厂实现。此接口由供应商工厂实现后,提供程序的管理控制台管理页面会显示附加选项。您可以通过单击按钮手动强制进行同步。这会调用 ImportSynchronization.sync ()
方法。另外,还会显示其他配置选项,供您自动调度同步。自动同步调用 syncSince ()
方法。