7.5. 設定方法
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.5.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} 文字列はサーバーの configuration/ ディレクトリーに対応し、この例では役に立ちます。
次に、古い 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.5.2. 管理コンソールでのプロバイダーの設定 リンクのコピーリンクがクリップボードにコピーされました!
設定が有効になったため、管理コンソールでプロバイダーを設定する際に path 変数を設定できます。