7.6. 設定方法
PropertyFileUserStorageProvider
の例は少々工夫されています。これは、プロバイダーの jar に組み込まれているプロパティーファイルにハードコーディングされているので、あまり便利ではありません。プロバイダーのインスタンスごとにこのファイルの場所を設定する場合があります。言い換えると、このプロバイダーを複数の異なるレルムで複数回再利用したり、全く異なるユーザープロパティーファイルを参照する場合などです。また、管理コンソール UI 内でこの設定を実行する必要があります。
UserStorageProviderFactory
には、プロバイダー設定を実装できる追加のメソッドがあります。プロバイダーごとに設定する変数を記述すると、管理コンソールは自動的に一般的な入力ページをレンダリングしてこの設定を収集します。実装されている場合、コールバックメソッドは、設定が保存される前、プロバイダーが初めて作成されるとき、および更新されるときにも検証を行います。UserStorageProviderFactory
は、org.keycloak.component.ComponentFactory
インターフェイスからこれらのメソッドを継承します。
List<ProviderConfigProperty> getConfigProperties(); default void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) throws ComponentValidationException { } default void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) { } default void onUpdate(KeycloakSession session, RealmModel realm, ComponentModel model) { }
ComponentFactory.getConfigProperties()
メソッドは、org.keycloak.provider.ProviderConfigProperty
インスタンスのリストを返します。これらのインスタンスは、プロバイダーの各設定変数のレンダリングおよび保存に必要なメタデータを宣言します。
7.6.1. 設定例
PropertyFileUserStorageProviderFactory
の例を拡張して、プロバイダーインスタンスをディスク上の特定のファイルを指定できるようにします。
PropertyFileUserStorageProviderFactory
public class PropertyFileUserStorageProviderFactory implements UserStorageProviderFactory<PropertyFileUserStorageProvider> { protected static final List<ProviderConfigProperty> configMetadata; static { configMetadata = ProviderConfigurationBuilder.create() .property().name("path") .type(ProviderConfigProperty.STRING_TYPE) .label("Path") .defaultValue("${jboss.server.config.dir}/example-users.properties") .helpText("File path to properties file") .add().build(); } @Override public List<ProviderConfigProperty> getConfigProperties() { return configMetadata; }
ProviderConfigurationBuilder
クラスは、設定プロパティーのリストを作成するためのヘルパークラスです。ここでは、String タイプである path
という名前の変数を指定します。このプロバイダーの管理コンソール設定ページでは、この設定変数は Path
としてラベル付けされ、デフォルト値は ${jboss.server.config.dir}/example-users.properties
です。この設定オプションのツールチップにカーソルを合わせると、ヘルプテキスト (File path to properties file (プロパティーファイルへのファイルパス)
) が表示されます。
次に、このファイルがディスクに存在することを確認します。有効なユーザープロパティーファイルを参照しない限り、レルムでこのプロバイダーのインスタンスを有効するべきではありません。これを実行するには、validateConfiguration()
メソッドを実装します。
@Override public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel config) throws ComponentValidationException { String fp = config.getConfig().getFirst("path"); if (fp == null) throw new ComponentValidationException("user property file does not exist"); fp = EnvUtil.replace(fp); File file = new File(fp); if (!file.exists()) { throw new ComponentValidationException("user property file does not exist"); } }
validateConfiguration()
メソッドは、ComponentModel
から設定変数を提供して、そのファイルがディスク上に存在するかどうかを確認します。org.keycloak.common.util.EnvUtil.replace()
メソッドを使用していることに注目してください。このメソッドを使用すると、${}
を含む文字列で、その値がシステムプロパティー値に置き換えられます。${jboss.server.config.dir}
文字列はサーバーの conf/
ディレクトリーに対応するものであり、この例では非常に役立ちます。
次に、古い init()
メソッドを削除します。ユーザープロパティーファイルはプロバイダーインスタンスごとに一意であるため、これを行います。このロジックは create()
メソッドに移動します。
@Override public PropertyFileUserStorageProvider create(KeycloakSession session, ComponentModel model) { String path = model.getConfig().getFirst("path"); Properties props = new Properties(); try { InputStream is = new FileInputStream(path); props.load(is); is.close(); } catch (IOException e) { throw new RuntimeException(e); } return new PropertyFileUserStorageProvider(session, model, props); }
全トランザクションでユーザープロパティーファイル全体をディスクから読み取るので、当然このロジックは効率的ではありませんが、今回の例で、設定変数をフックする方法をシンプルに説明できたかと思います。
7.6.2. 管理コンソールでのプロバイダーの設定
設定が有効になったため、管理コンソールでプロバイダーを設定する際に path
変数を設定できます。