第6章 SPI (サービスプロバイダーインターフェイス)
Red Hat build of Keycloak は、カスタムコードを必要とせずにほとんどのユースケースに対応するように設計されていますが、カスタマイズ性も望まれています。そのため、Red Hat build of Keycloak には、独自プロバイダーの実装を可能にする数多くの SPI (サービスプロバイダーインターフェイス) があります。
6.1. SPI の実装
SPI を実装するには、その ProviderFactory および Provider インターフェイスを実装する必要があります。サービス設定ファイルも作成する必要があります。
たとえば、Theme Selector SPI を実装するには、ThemeSelectorProviderFactory および ThemeSelectorProvider を実装し、さらに META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
ファイルも指定する必要があります。
ThemeSelectorProviderFactory の例:
package org.acme.provider; import ... public class MyThemeSelectorProviderFactory implements ThemeSelectorProviderFactory { @Override public ThemeSelectorProvider create(KeycloakSession session) { return new MyThemeSelectorProvider(session); } @Override public void init(Config.Scope config) { } @Override public void postInit(KeycloakSessionFactory factory) { } @Override public void close() { } @Override public String getId() { return "myThemeSelector"; } }
プロバイダーファクトリーの実装では、getId()
メソッドによって一意の ID を返すことを推奨します。ただし、以下の プロバイダーのオーバーライド セクションで説明するように、このルールには例外が存在する場合があります。
Red Hat build of Keycloak はプロバイダーファクトリーの単一のインスタンスを作成するので、複数の要求の状態を保存できます。プロバイダーのインスタンスは、各要求のファクトリーで create を呼び出すことで作成されるので、軽量オブジェクトでなければなりません。
ThemeSelectorProvider の例:
package org.acme.provider; import ... public class MyThemeSelectorProvider implements ThemeSelectorProvider { public MyThemeSelectorProvider(KeycloakSession session) { } @Override public String getThemeName(Theme.Type type) { return "my-theme"; } @Override public void close() { } }
サービス設定ファイルの例 (META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
):
org.acme.provider.MyThemeSelectorProviderFactory
プロバイダーを設定するには、プロバイダーの設定 の章を参照してください。
たとえば、プロバイダーを設定するには、次のようにオプションを設定できます。
bin/kc.[sh|bat] --spi-theme-selector-my-theme-selector-enabled=true --spi-theme-selector-my-theme-selector-theme=my-theme
その後、init メソッド ProviderFactory
で設定を取得できます。
public void init(Config.Scope config) { String themeName = config.get("theme"); }
必要に応じて、プロバイダーは他のプロバイダーを検索することもできます。以下に例を示します。
public class MyThemeSelectorProvider implements ThemeSelectorProvider { private KeycloakSession session; public MyThemeSelectorProvider(KeycloakSession session) { this.session = session; } @Override public String getThemeName(Theme.Type type) { return session.getContext().getRealm().getLoginTheme(); } }
6.1.1. ビルトインプロバイダーのオーバーライド
前述したように、ProviderFactory
の実装では一意の ID を使用することを推奨します。ただし、同時に、Red Hat build of Keycloak のビルトインプロバイダーの 1 つをオーバーライドすると便利な場合があります。この場合に推奨される方法は、一意の ID を使用して ProviderFactory を実装し、たとえば プロバイダーの設定 の章で指定されているようにデフォルトのプロバイダーを設定することです。一方で、これが常に可能であるとは限りません。
たとえば、デフォルトの OpenID Connect プロトコルの動作にいくつかのカスタマイズが必要で、OIDCLoginProtocolFactory
のデフォルトの Red Hat build of Keycloak 実装をオーバーライドする場合は、同じ providerId を保持する必要があります。たとえば、管理コンソール、OIDC プロトコルの既知のエンドポイント、およびその他のさまざまなものは、プロトコルファクトリーの ID が openid-connect
であることを前提としています。
この場合、カスタム実装のメソッド order()
を実装し、その順序をビルトインの実装よりも上位にすることを強く推奨します。
public class CustomOIDCLoginProtocolFactory extends OIDCLoginProtocolFactory { // Some customizations here @Override public int order() { return 1; } }
同じプロバイダー ID を持つ実装が複数ある場合、最上位の実装のみが Red Hat build of Keycloak ランタイムによって使用されます。
6.1.2. 管理コンソールで SPI 実装からの情報を表示
プロバイダーに関する追加情報を Red Hat build of Keycloak 管理者に表示すると便利な場合があります。プロバイダーのビルド時間情報 (現在インストールされているカスタムプロバイダーのバージョンなど)、プロバイダーの現在の設定 (プロバイダーが通信するリモートシステムの URL)、または一部の運用情報 (プロバイダーが対話するリモートシステムからの応答時間) を表示できます。Red Hat build of Keycloak 管理コンソールには、そのような情報を表示するサーバー情報ページがあります。
プロバイダーからの情報を表示するには、ProviderFactory
に org.keycloak.provider.ServerInfoAwareProviderFactory
インターフェイスを実装するだけで十分です。
前の例の MyThemeSelectorProviderFactory
の実装例:
package org.acme.provider; import ... public class MyThemeSelectorProviderFactory implements ThemeSelectorProviderFactory, ServerInfoAwareProviderFactory { ... @Override public Map<String, String> getOperationalInfo() { Map<String, String> ret = new LinkedHashMap<>(); ret.put("theme-name", "my-theme"); return ret; } }