为了账号安全,请及时绑定邮箱和手机立即绑定

Keycloak 用户存储 SPI 实现

Keycloak 用户存储 SPI 实现

FFIVE 2023-06-04 17:50:22
我正在尝试实现自定义 keycloack Authenticator SPI 以针对外部数据源进行身份验证。Spring boot Rest Service 也可以用,我也可以用那个。我要解决的用例是向用户显示 keycloak 登录屏幕。Onsubmission 用户根据外部数据源进行验证。从外部数据源中检索一些属性,将其映射到 keycloak 的 id 和访问令牌。还设置了同一用户同时多次登录的用户限制条件。我在想,这可以通过检索 keycloak 数据源中可用的用户会话信息来解决。如果我使用外部数据源,keycloak 是否仍然维护会话信息?我遵循了官方指南(https://www.keycloak.org/docs/latest/server_development/index.html#_auth_spi_walkthrough)的第 8.3 节,这与我需要的非常相似。现在我跳过并按照第 11 节开始(https://www.keycloak.org/docs/latest/server_development/index.html#_user-storage-spi)似乎也更合适。我所做的是从实施自定义身份验证器开始,SPI 认为这不是正确的方法,现在实施了 UserStorageProvider。/*** * From UserLookupProvider */public UserModel getUserById(String id, RealmModel realm) {    System.out.println("ID: " + id + ":REALM:" + realm);    StorageId storageId = new StorageId(id);    /**     * StorageId.getExternalId() method is invoked to obtain      * the username embeded in the id parameter     */    String username = storageId.getExternalId();    System.out.println("Name:" + username);    return getUserByUsername(username, realm);}/*** * From UserLookupProvider * This method is invoked by the Keycloak login page when a user logs in */按照文档(https://www.keycloak.org/docs/latest/server_development/index.html#packaging-and-deployment-2)我们的提供者实现的类文件应该放在一个 jar 中。您还必须在 META-INF/services/org.keycloak.storage.UserStorageProviderFactory 文件中声明提供者工厂类。这里的问题是:我创建的 jar 在“META-INF”文件夹中没有服务目录,我需要手动创建并添加它吗?org.keycloak.examples.federation.properties.FilePropertiesStorageFactory 创建 jar 后,您可以使用常规的 WildFly 方式部署它:将 jar 复制到 deploy/ 目录或使用 JBoss CLI。使用 Maven 创建 jar 后,将 jar 复制到“keycloak-6.0.1\standalone\deployments”文件夹。但我没有在“用户联合列表”中看到我的提供者
查看完整描述

3 回答

?
MM们

TA贡献1886条经验 获得超2个赞

万一有人遇到这样的问题:

由于 META-INF/services 文件夹,UserStorage SPI 未显示。它在文档中提供,但不清楚

在 src/main/resources 中,创建文件夹结构 META-INF/services

在 META-INF/services 目录中创建一个名为 org.keycloak.storage.UserStorageProviderFactory 的文件(整个就是文件名)。它的内容是您的 SPI 的完全限定类名:com.test.UserSpi


查看完整回答
反对 回复 2023-06-04
?
弑天下

TA贡献1818条经验 获得超8个赞

  • 好的,您已阐明您需要一个用户存储提供程序 API。伟大的

  • 现在关于你的第二个“问题/挑战”:

从外部数据源中检索一些属性,将其映射到 keycloak 的 id 和访问令牌。需要检索用户唯一 ID 并将其添加为 jwt 中的主题 ID。这是 id,当此令牌传递给其他服务时,其余服务可用于检索 id。

为此,你能做的最好的事情是:

  1. 添加这些用户的唯一数据作为用户属性(在管理控制台上查看)

  2. 在 Keycloak 上创建一个“客户端范围”,使用“用户属性”的映射器将您想要(从您的用户)添加的那些属性映射到您的 Id-token 和 access-token。您还需要将您的客户与您刚刚创建的“客户范围”联系起来。

查看完整回答
反对 回复 2023-06-04
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

我不确定你需要什么。让我们从区分 Authentication SPI(联合身份检查)和 User Provider SPI(联合用户)开始。第一个(文档的第 8 节 - 更多地关注针对外部服务对用户进行身份验证 - 类似于 facebook 或 google)。联合用户存储更像是您在具有遗留“角色结构”的遗留系统中拥有自己的用户,并且您基本上想通过 keycloak 管理它们(通过导入它们,或者通过某些 API 查询 - 这将是部分该文档的 11)。因此,请确定您确实需要什么。


第二,你提到以下内容:


>  User is presented keycloak login screen. Onsubmission User is

> validated against external Datasource.

> Retrieve some attributes from external datasource, map it to

> keycloak's id and access token.

> Also put in a condition of user restriction of same user logging in

> multiple times at the same time.

> I was thinking, it could be solved by retrieving user session

> information that's available in the keycloak datasource. If i use

> external datasource, does keycloak still maintain session information?

你的意思是:从外部数据源中检索一些属性,将其映射到 keycloak 的 id 和访问令牌。?通常您只检索用户核心信息,可能还有角色和其他自定义属性(不是会话信息)。Keycloak 本身作为基于 openIDConnect 的授权服务器,将生成访问令牌,其中已经包含有关哪些受保护资源可以被谁访问的信息,因此您实际上不需要从其他地方导入任何会话,也不必担心上述令牌的生成.


关于: 还设置了同一用户同时多次登录的用户限制条件。当您第一次登录时,您到底想完成(或避免什么?)您的客户收到一个有效时间为 X 的 Bearer 令牌,在那段时间内您不需要再次登录,直到令牌过期或被删除;再次是您的 Auth 服务器负责的事情,而不是您实现的事情。您想要更具体的东西吗?


我在想,这可以通过检索 keycloak 数据源中可用的用户会话信息来解决。如果我使用外部数据源,keycloak 是否仍然维护会话信息?这听起来不对,你指的是什么会话数据?或者你需要访问?您的用户数据、范围、角色等可以通过 KEycloak Rest API ( https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_overview )访问。您的外部数据源用于与用户相关的核心数据(不是外部会话),您为什么认为需要导入外部会话?


查看完整回答
反对 回复 2023-06-04
  • 3 回答
  • 0 关注
  • 240 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信