第7章 ユーザーストレージ SPI
ユーザーストレージ SPI を使用して拡張機能を Red Hat build of Keycloak に書き込み、外部ユーザーデータベースおよび認証情報ストアに接続できます。組み込み LDAP および ActiveDirectory サポートは、この SPI 動作を実装したものです。Red Hat build of Keycloak は、追加設定なしでローカルデータベースを使用して、ユーザーを作成、更新、検索し、クレデンシャルを検証します。ただし、多くの場合、組織には Red Hat build of Keycloak のデータモデルに移行できない既存の外部プロプライエタリーユーザーデータベースがあります。このような状況では、アプリケーション開発者は User Storage SPI の実装を記述して、Red Hat build of Keycloak がユーザーのログインと管理に使用する外部ユーザーストアと内部ユーザーオブジェクトモデルを橋渡しできます。
ユーザーログイン時などに Red Hat build of Keycloak ランタイムがユーザーを検索する必要がある場合は、複数の手順を実行してユーザーを特定します。まず、ユーザーキャッシュにユーザーが含まれているかどうかを確認します。ユーザーが見つかった場合にはユーザーがそのインメモリー表現を使用しているかを確認します。次に、Red Hat build of Keycloak ローカルデータベース内でユーザーを検索します。ユーザーが見つからない場合は、ランタイムが探しているユーザーをいずれかの実装が返すまで、User Storage SPI プロバイダー実装全体をループして、ユーザークエリーを実行し続けます。プロバイダーは、ユーザーの外部ユーザーストアをクエリーし、ユーザーの外部データ表現を Red Hat build of Keycloak のユーザーメタモデルにマップします。
User Storage SPI プロバイダー実装は、複雑な基準クエリーの実行、ユーザーへの CRUD 操作の実行、認証情報の検証および管理、または多数のユーザーの一括更新を実行することもできます。これは、外部ストアの機能により異なります。
User Storage SPI プロバイダー実装は、Jakarta EE コンポーネントと同様にパッケージ化およびデプロイされます。これらはデフォルトでは有効になっていませんが、管理コンソールの User Federation
タブでレルムごとに有効および設定する必要があります。
ユーザープロバイダーの実装で、ユーザー属性をユーザーアイデンティティーのリンク/確立のためのメタデータ属性として使用している場合は、ユーザーが属性を編集できないようにし、対応する属性が読み取り専用になっていることを確認してください。これは LDAP_ID
属性の例で、ビルトインの Red Hat build of Keycloak LDAP プロバイダーが LDAP サーバー側でユーザーの ID を保存するために使用しています。詳細は、脅威モデルの軽減策 の章を参照してください。
Red Hat build of Keycloak Quickstarts Repository に 2 つのサンプルプロジェクトがあります。各クイックスタートには README
ファイルがあり、サンプルアプリケーションをビルド、デプロイ、およびテストする方法が記載されています。次の表は、利用可能な User Storage SPI クイックスタートの簡単な説明を示しています。
Name | 説明 |
---|---|
JPA を使用してユーザーストレージプロバイダーを実装する方法を説明しています。 | |
ユーザー名とパスワードのキーペアが含まれる単純なプロパティーファイルを使用して、ユーザーストレージプロバイダーを実装する方法を説明しています。 |
7.1. プロバイダーインターフェイス
User Storage SPI の実装を構築する場合は、プロバイダークラスとプロバイダーファクトリーを定義する必要があります。プロバイダークラスインスタンスは、プロバイダーファクトリーによってトランザクションごとに作成されます。プロバイダークラスは、ユーザー検索やその他のユーザー操作で負荷が大きい作業をすべて行います。org.keycloak.storage.UserStorageProvider
インターフェイスを実装する必要があります。
package org.keycloak.storage; public interface UserStorageProvider extends Provider { /** * Callback when a realm is removed. Implement this if, for example, you want to do some * cleanup in your user storage when a realm is removed * * @param realm */ default void preRemove(RealmModel realm) { } /** * Callback when a group is removed. Allows you to do things like remove a user * group mapping in your external store if appropriate * * @param realm * @param group */ default void preRemove(RealmModel realm, GroupModel group) { } /** * Callback when a role is removed. Allows you to do things like remove a user * role mapping in your external store if appropriate * @param realm * @param role */ default void preRemove(RealmModel realm, RoleModel role) { } }
UserStorageProvider
インターフェイスはほんのわずかであると思われるかもしれません。この章では後で、ユーザー統合のサポート向けにプロバイダーが実装する可能性のあるさまざまなインターフェイスが他にあることを説明します。
UserStorageProvider
インスタンスは、トランザクションごとに 1 度作成されます。トランザクションが完了すると、UserStorageProvider.close()
メソッドが呼び出され、インスタンスはガベージコレクションされます。インスタンスはプロバイダーファクトリーによって作成されます。プロバイダーファクトリーは org.keycloak.storage.UserStorageProviderFactory
インターフェイスを実装します。
package org.keycloak.storage; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public interface UserStorageProviderFactory<T extends UserStorageProvider> extends ComponentFactory<T, UserStorageProvider> { /** * This is the name of the provider and will be shown in the admin console as an option. * * @return */ @Override String getId(); /** * called per Keycloak transaction. * * @param session * @param model * @return */ T create(KeycloakSession session, ComponentModel model); ... }
プロバイダーファクトリークラスは、UserStorageProviderFactory
を実装する際に、具体的なプロバイダークラスをテンプレートパラメーターとして指定する必要があります。これはランタイムがこのクラスをイントロスペクションしてその機能 (実装する他のインターフェイス) をスキャンするため必要です。たとえば、プロバイダークラスの名前が FileProvider
の場合、ファクトリークラスは以下のようになります。
public class FileProviderFactory implements UserStorageProviderFactory<FileProvider> { public String getId() { return "file-provider"; } public FileProvider create(KeycloakSession session, ComponentModel model) { ... }
getId()
メソッドは、User Storage プロバイダーの名前を返します。この ID は、特定のレルムのプロバイダーを有効にする際に管理コンソールのユーザーフェデレーションページに表示されます。
create()
メソッドは、プロバイダークラスのインスタンスを割り当てます。org.keycloak.models.KeycloakSession
パラメーターを取ります。このオブジェクトは、その他の情報およびメタデータを検索し、ランタイム内の他のコンポーネントへのアクセスを提供するために使用できます。ComponentModel
パラメーターは、プロバイダーが特定のレルム内でどのように有効および設定されたかを表します。これには、有効化されたプロバイダーのインスタンス ID と、管理コンソールで有効にした場合に指定できる設定が含まれます。
UserStorageProviderFactory
には他の機能があり、この後、この章で取り上げます。