Keycloak 用户存储 SPI 实现

我正在尝试实现自定义 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”文件夹。但我没有在“用户联合列表”中看到我的提供者


FFIVE
浏览 241回答 3
3回答

MM们

万一有人遇到这样的问题:由于 META-INF/services 文件夹,UserStorage SPI 未显示。它在文档中提供,但不清楚在 src/main/resources 中,创建文件夹结构 META-INF/services在 META-INF/services 目录中创建一个名为 org.keycloak.storage.UserStorageProviderFactory 的文件(整个就是文件名)。它的内容是您的 SPI 的完全限定类名:com.test.UserSpi

弑天下

好的,您已阐明您需要一个用户存储提供程序 API。伟大的现在关于你的第二个“问题/挑战”:从外部数据源中检索一些属性,将其映射到 keycloak 的 id 和访问令牌。需要检索用户唯一 ID 并将其添加为 jwt 中的主题 ID。这是 id,当此令牌传递给其他服务时,其余服务可用于检索 id。为此,你能做的最好的事情是:添加这些用户的唯一数据作为用户属性(在管理控制台上查看)在 Keycloak 上创建一个“客户端范围”,使用“用户属性”的映射器将您想要(从您的用户)添加的那些属性映射到您的 Id-token 和 access-token。您还需要将您的客户与您刚刚创建的“客户范围”联系起来。

蛊毒传说

我不确定你需要什么。让我们从区分 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 )访问。您的外部数据源用于与用户相关的核心数据(不是外部会话),您为什么认为需要导入外部会话?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java