サーバー開発者ガイド
概要
第1章 はじめに リンクのコピーリンクがクリップボードにコピーされました!
サンプルのリストでは、1 行に表示されるものが、利用可能なページ幅に収まらない場合があります。これらの行は、分割されています。行末の '\' は、ページに収まるように改行が追加され、次の行がインデントされていることを示しています。つまり、
Let's pretend to have an extremely \ long line that \ does not fit This one is short
Let's pretend to have an extremely \
long line that \
does not fit
This one is short
上記は、以下を指します。
Let's pretend to have an extremely long line that does not fit This one is short
Let's pretend to have an extremely long line that does not fit
This one is short
第2章 管理 REST API リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak には、管理コンソールの全機能が含まれる、完全に機能する管理 REST API が同梱されています。
API を呼び出すには、適切な権限を持つアクセストークンを取得する必要があります。必要な権限については、サーバー管理ガイド に記載されています。
Red Hat build of Keycloak を使用してアプリケーションの認証を有効にすることで、トークンを取得できます。アプリケーションおよびサービスのセキュリティー保護ガイドを参照してください。直接アクセス許可を使用して、アクセストークンを取得することもできます。
2.1. CURL の使用例 リンクのコピーリンクがクリップボードにコピーされました!
2.1.1. ユーザー名とパスワードでの認証 リンクのコピーリンクがクリップボードにコピーされました!
次の例では、スタートガイド のチュートリアルのとおり、パスワード password
を使用してユーザー admin
を master
レルムに作成したことを前提としています。
手順
ユーザー名
admin
およびパスワードpassword
を使用して、master
レルムのユーザーのアクセストークンを取得します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注記デフォルトでは、このトークンは 1 分で有効期限が切れます。
結果は JSON 形式のドキュメントになります。
-
access_token
プロパティーの値を抽出して、必要な API を呼び出します。 API へのリクエストの
Authorization
ヘッダーに値を追加して、API を呼び出します。以下の例は、master レルムの詳細を取得する方法を示しています。
curl \ -H "Authorization: bearer eyJhbGciOiJSUz..." \ "http://localhost:8080/admin/realms/master"
curl \ -H "Authorization: bearer eyJhbGciOiJSUz..." \ "http://localhost:8080/admin/realms/master"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.1.2. サービスアカウントでの認証 リンクのコピーリンクがクリップボードにコピーされました!
client_id
および client_secret
を使用し、Admin REST API に対して認証するには、この手順を実行します。
手順
クライアントが次のように設定されていることを確認してください。
-
client_id
は、レルム マスター に所属する 機密 クライアントです。 -
client_id
がService Accounts Enabled
オプションを有効にしています。 client_id
には、カスタムの "Audience" マッパーがあります。-
含まれるクライアントオーディエンス:
security-admin-console
-
含まれるクライアントオーディエンス:
-
-
"Service Account Roles" タブで
client_id
に 'admin' というロールが割り当てられていることを確認します。
curl \ -d "client_id=<YOUR_CLIENT_ID>" \ -d "client_secret=<YOUR_CLIENT_SECRET>" \ -d "grant_type=client_credentials" \ "http://localhost:8080/realms/master/protocol/openid-connect/token"
curl \
-d "client_id=<YOUR_CLIENT_ID>" \
-d "client_secret=<YOUR_CLIENT_SECRET>" \
-d "grant_type=client_credentials" \
"http://localhost:8080/realms/master/protocol/openid-connect/token"
2.2. 関連情報 リンクのコピーリンクがクリップボードにコピーされました!
第3章 テーマ リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、Web ページとメールでテーマを使用できます。これにより、エンドユーザーに表示されるページのルックアンドフィールをカスタマイズでき、アプリケーションと統合できます。
図3.1 sunrise のサンプルテーマを含むログインページ
3.1. テーマのタイプ リンクのコピーリンクがクリップボードにコピーされました!
テーマには 1 つ以上のタイプがあり、Red Hat build of Keycloak のさまざまな側面のカスタマイズに使用できます。利用可能なタイプは以下のとおりです。
- Account - アカウントコンソール
- Admin - 管理コンソール
- Email - メール
- Login - ログインフォーム
- Welcome - Welcome ページ
3.2. テーマの設定 リンクのコピーリンクがクリップボードにコピーされました!
Welcome を除くすべてのテーマタイプは、管理コンソールを介して設定されます。
手順
- 管理コンソールにログインします。
- 左上隅のドロップダウンボックスからレルムを選択します。
- メニューで Realm Settings をクリックします。
Themes タブをクリックします。
注記master
管理コンソールのテーマを設定するには、master
レルムの管理コンソールテーマを設定する必要があります。- 管理コンソールへの変更を表示するには、ページをリフレッシュします。
-
spi-theme-welcome-theme
オプションを使用して welcome テーマを変更します。 以下に例を示します。
bin/kc.[sh|bat] start --spi-theme-welcome-theme=custom-theme
bin/kc.[sh|bat] start --spi-theme-welcome-theme=custom-theme
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
3.3. デフォルトのテーマ リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、サーバーディストリビューション内の JAR ファイル keycloak-themes-26.0.5.redhat-00003.jar
のデフォルトテーマにバンドルされています。サーバーのルートの themes
ディレクトリーには、デフォルトでテーマが含まれていませんが、デフォルトテーマに関する追加の詳細が記載された README ファイルが含まれています。アップグレードを簡略化するために、バンドルされているテーマを直接編集しないでください。代わりに、独自のテーマを作成して、バンドルされたテーマのいずれかを拡張します。
3.4. テーマの作成 リンクのコピーリンクがクリップボードにコピーされました!
テーマは次のもので構成されます。
- HTML テンプレート (Freemarker テンプレート)
- イメージ
- メッセージバンドル
- スタイルシート
- スクリプト
- テーマのプロパティー
すべてのページを置き換える予定がない限り、別のテーマを拡張することを推奨します。ほとんどの場合、既存のテーマを拡張することになるでしょう。または、管理コンソールまたはアカウントコンソールの独自の実装を提供する場合は、base
テーマを拡張することを検討してください。base
テーマはメッセージバンドルで構成されているため、メインの index.ftl
Freemarker テンプレートの実装を含め、実装を最初から開始する必要があります。ただし、メッセージバンドルから既存の翻訳を活用することができます。
テーマを拡張する場合は、個別のリソース (テンプレート、スタイルシートなど) をオーバーライドできます。HTML テンプレートの上書きをすることにした場合は、新しいリリースにアップグレードする際にカスタムテンプレートを更新する必要があることに注意してください。
テーマを作成する際に、Red Hat build of Keycloak を再起動せずに themes
ディレクトリーから直接テーマリソースを編集できるため、キャッシングを無効にするとを推奨します。
手順
以下のオプションを指定して Keycloak を実行します。
bin/kc.[sh|bat] start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false
bin/kc.[sh|bat] start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false
Copy to Clipboard Copied! Toggle word wrap Toggle overflow themes
ディレクトリーにディレクトリーを作成します。ディレクトリーの名前はテーマの名前になります。たとえば、
mytheme
というテーマを作成するには、themes/mytheme
ディレクトリーを作成します。theme ディレクトリーには、テーマが提供するタイプごとにディレクトリーを作成します。
たとえば、ログインタイプを
mytheme
テーマに追加するには、themes/mytheme/login
ディレクトリーを作成します。それぞれのタイプに対して、テーマの設定を可能にする
theme.properties
ファイルを作成します。たとえば、テーマ
themes/mytheme/login
を設定してbase
テーマを拡張し、いくつかの共通リソースをインポートするには、次の内容を含むファイルthemes/mytheme/login/theme.properties
を作成します。parent=base import=common/keycloak
parent=base import=common/keycloak
Copy to Clipboard Copied! Toggle word wrap Toggle overflow これで、ログインタイプのサポートのあるテーマが作成されました。
- 管理コンソールにログインし、新しいテーマをチェックアウトします。
- レルムを選択します。
- メニューで Realm Settings をクリックします。
- Themes タブをクリックします。
- Login Theme については mytheme を選択し、Save をクリックします。
レルムのログインページを開きます。
これは、アプリケーションからログインするか、アカウントコンソール (
/realms/{realm name}/account
) を開くことによって実行できます。-
親テーマの変更の効果を確認するには、
parent=keycloak
intheme.properties
に設定し、ログインページを更新します。
パフォーマンスに大きく影響するため、必ず実稼働環境でキャッシュを再度有効にしてください。
テーマキャッシュのコンテンツを手動で削除する場合は、サーバーディストリビューションの data/tmp/kc-gzip-cache
ディレクトリーを削除することで実行できます。これは、たとえば、以前のサーバー実行の際にテーマのキャッシュを無効にせずにカスタムプロバイダーまたはカスタムテーマを再デプロイした場合に便利です。
3.4.1. テーマのプロパティー リンクのコピーリンクがクリップボードにコピーされました!
テーマプロパティーは、テーマディレクトリーの <THEME TYPE>/theme.properties
ファイルで設定されます。
- parent - 拡張する親テーマ
- import - 別のテーマからのリソースのインポート
-
common - 共通リソースパスをオーバーライドします。指定しない場合のデフォルト値は
common/keycloak
です。この値は、${url.resourcesCommonPath}
の接尾辞の値として、通常、freemarker テンプレートで使用されます (${url.resoucesCommonPath}
値の接頭辞はテーマのルート URI です)。 - styles - 追加するスタイルのスペース区切りリスト
- locales - サポートされるロケールのコンマ区切りリスト
特定の要素タイプに使用される css クラスを変更するために使用できるプロパティーのリストがあります。これらのプロパティーのリストは、keycloak テーマ (themes/keycloak/<THEME TYPE>/theme.properties
) の対応するタイプの theme.properties ファイルを参照してください。
独自のカスタムプロパティーを追加して、カスタムテンプレートから使用することもできます。
これを行うには、次の形式を使用してシステムプロパティーまたは環境変数を置き換えることができます。
-
${some.system.property}
- システムプロパティーの場合。 -
${env.ENV_VAR}
- 環境変数の場合。
システムプロパティーまたは環境変数が ${foo:defaultValue}
で見つからない場合は、デフォルト値を指定することもできます。
デフォルト値が指定されておらず、対応するシステムプロパティーまたは環境変数がない場合は、何も置き換えられず、テンプレートの形式が使用されることになります。
以下は、実現できる例の一部です。
javaVersion=${java.version} unixHome=${env.HOME:Unix home not found} windowsHome=${env.HOMEPATH:Windows home not found}
javaVersion=${java.version}
unixHome=${env.HOME:Unix home not found}
windowsHome=${env.HOMEPATH:Windows home not found}
3.4.2. テーマにスタイルシートを追加 リンクのコピーリンクがクリップボードにコピーされました!
テーマに 1 つ以上のスタイルシートを追加できます。
手順
-
テーマの
<THEME TYPE>/resources/css
ディレクトリーにファイルを作成します。 それを
theme.properties
のstyles
プロパティーに追加します。たとえば、
styles.css
をmytheme
に追加するには、以下の内容を含むthemes/mytheme/login/resources/css/styles.css
を作成します。.login-pf body { background: DimGrey none; }
.login-pf body { background: DimGrey none; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow themes/mytheme/login/theme.properties
を編集し、以下を追加します。styles=css/styles.css
styles=css/styles.css
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 変更を確認するには、レルムのログインページを開きます。
適用されるスタイルは、カスタムのスタイルシートからのものだけであることに注目してください。
親テーマのスタイルを含めるには、そのテーマのスタイルを読み込みます。
themes/mytheme/login/theme.properties
を編集し、styles
を次のように変更します。styles=css/login.css css/styles.css
styles=css/login.css css/styles.css
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注記親スタイルシートのスタイルをオーバーライドするには、スタイルシートが最後にリストされていることを確認してください。
3.4.3. テーマにスクリプトを追加 リンクのコピーリンクがクリップボードにコピーされました!
1 つ以上のスクリプトをテーマに追加できます。
手順
-
テーマの
<THEME TYPE>/resources/js
ディレクトリーにファイルを作成します。 ファイルを
theme.properties
のscripts
プロパティーに追加します。たとえば、
script.js
をmytheme
に追加するには、以下の内容でthemes/mytheme/login/resources/js/script.js
を作成します。alert('Hello');
alert('Hello');
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 次に、
themes/mytheme/login/theme.properties
を編集し、以下を追加します。scripts=js/script.js
scripts=js/script.js
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
3.4.4. テーマにイメージを追加 リンクのコピーリンクがクリップボードにコピーされました!
テーマがイメージを使用できるようにするには、テーマの <THEME TYPE>/resources/img
ディレクトリーにイメージを追加します。これらはスタイルシート内から使用することも、HTML テンプレートで直接使用することもできます。
たとえば、イメージを mytheme
に追加するには、イメージを themes/mytheme/login/resources/img/image.jpg
にイメージをコピーします。
次に、以下を使用して、カスタムスタイルシート内からこのイメージを使用できます。
body { background-image: url('../img/image.jpg'); background-size: cover; }
body {
background-image: url('../img/image.jpg');
background-size: cover;
}
または、HTML テンプレートで直接使用するには、以下をカスタム HTML テンプレートに追加します。
<img src="${url.resourcesPath}/img/image.jpg" alt="My image description">
<img src="${url.resourcesPath}/img/image.jpg" alt="My image description">
3.4.5. メールテーマへの画像の追加 リンクのコピーリンクがクリップボードにコピーされました!
テーマで画像を使用できるようにするには、テーマの <THEME TYPE>/email/resources/img
ディレクトリーに画像を追加します。この画像は HTML テンプレート内で直接使用できます。
たとえば、mytheme
に画像を追加するには、画像を themes/mytheme/email/resources/img/logo.jpg
にコピーします。
HTML テンプレートで直接使用するには、カスタム HTML テンプレートに以下を追加します。
<img src="${url.resourcesUrl}/img/image.jpg" alt="My image description">
<img src="${url.resourcesUrl}/img/image.jpg" alt="My image description">
3.4.6. メッセージ リンクのコピーリンクがクリップボードにコピーされました!
テンプレートのテキストは、メッセージバンドルからロードされます。別のテーマを拡張するテーマは、親のメッセージバンドルからすべてのメッセージを継承し、<THEME TYPE>/messages/messages_en.properties
をテーマに追加して個別のメッセージを上書きできます。
たとえば、ログインフォーム上の Username
を、mytheme
の Your Username
に置き換えるには、以下の内容で themes/mytheme/login/messages/messages_en.properties
ファイルを作成します。
usernameOrEmail=Your Username
usernameOrEmail=Your Username
メッセージの使用時に {0}
や {1}
などのメッセージ値内では引数に置き換えられます。たとえば、Log in to {0}
の {0} はレルム名に置き換えられます。
これらのメッセージバンドルのテキストは、レルム固有の値で上書きすることができます。レルム固有の値は、UI や API で管理できます。
3.4.7. レルムに言語を追加 リンクのコピーリンクがクリップボードにコピーされました!
前提条件
- レルムの国際化を有効にするには、サーバー管理ガイド を参照してください。
手順
-
テーマのディレクトリーに
<THEME TYPE>/messages/messages_<LOCALE>.properties
ファイルを作成します。 このファイルを
<THEME TYPE>/theme.properties
のlocales
プロパティーに追加します。言語をユーザーが利用できるようにするには、レルムのlogin
、account
およびemail
テーマがその言語をサポートしていなければならないため、これらのテーマタイプに言語を追加する必要があります。たとえば、
mytheme
テーマにノルウェー語の翻訳を追加するには、以下の内容でthemes/mytheme/login/messages/messages_no.properties
ファイルを作成します。usernameOrEmail=Brukernavn password=Passord
usernameOrEmail=Brukernavn password=Passord
Copy to Clipboard Copied! Toggle word wrap Toggle overflow メッセージの翻訳を省略すると、英語が使用されます。
themes/mytheme/login/theme.properties
を編集し、以下を追加します。locales=en,no
locales=en,no
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
account
とemail
のテーマタイプにも同じものを追加します。そのためには、themes/mytheme/account/messages/messages_no.properties
およびthemes/mytheme/email/messages/messages_no.properties
を作成します。これらのファイルを空のままにすると、英語のメッセージが使用されます。 -
themes/mytheme/login/theme.properties
をthemes/mytheme/account/theme.properties
およびthemes/mytheme/email/theme.properties
にコピーします。 言語セレクターの翻訳を追加します。これには、英語の翻訳にメッセージを追加します。これには、以下を
themes/mytheme/account/messages/messages_en.properties
およびthemes/mytheme/login/messages/messages_en.properties
に追加します。locale_no=Norsk
locale_no=Norsk
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
デフォルトでは、メッセージプロパティーファイルは UTF-8 を使用してエンコードする必要があります。Keycloak は、内容を UTF-8 として読み取れない場合、ISO-8859-1 処理にフォールバックします。Java の PropertyResourceBundle のドキュメントで説明されているように、Unicode 文字をエスケープできます。以前のバージョンの Keycloak では、# encoding: UTF-8
のようなコメントを使用して最初の行にエンコーディングを指定することがサポートされていました。これはサポートされなくなりました。
3.4.8. カスタムアイデンティティープロバイダーのアイコンの追加 リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、ログイン画面に表示されるカスタムアイデンティティープロバイダーのアイコンの追加に対応しています。
手順
-
ログイン
theme.properties
ファイル (themes/mytheme/login/theme.properties
など) の中で、キーパターンkcLogoIdP-<alias>
でアイコンクラスを定義します。 myProvider
というエイリアスを持つ Identity プロバイダーの場合は、カスタムテーマのtheme.properties
ファイルに行を追加できます。以下に例を示します。kcLogoIdP-myProvider = fa fa-lock
kcLogoIdP-myProvider = fa fa-lock
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
すべてのアイコンは、PatternFly4 の公式 Web サイトで公開されています。ソーシャルプロバイダー用のアイコンは、base
ログインテーマのプロパティー (themes/keycloak/login/theme.properties
) ですでに定義されているため、それを参考にすることができます。
3.4.9. カスタム HTML テンプレートの作成 リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、Apache Freemarker テンプレートを使用して HTML を生成し、ページをレンダリングします。
カスタムテンプレートを作成してページのレンダリング方法を完全に変更することも可能ですが、組み込みテンプレートをできるだけ活用することを推奨します。理由は次のとおりです。
- アップグレード時に、新しいバージョンから最新の更新を取得するために、カスタムテンプレートを更新する必要がある場合があります。
- テーマに CSS スタイルを設定 すると、UI をご自身の UI 設計標準およびガイドラインに合わせて調整できます。
- ユーザープロファイルを使用 すると、カスタムユーザー属性をサポートし、そのレンダリング方法を設定できます。
ほとんどの場合、Red Hat build of Keycloak をニーズに合わせて調整するためにテンプレートを変更する必要はありません。ただし、<THEME TYPE>/<TEMPLATE>.ftl
を作成することで、独自のテーマ内の個々のテンプレートをオーバーライドできます。管理者およびアカウントコンソールは、アプリケーションのレンダリングに単一のテンプレート index.ftl
を使用します。
他のテーマタイプのテンプレートのリストについては、$KEYCLOAK_HOME/lib/lib/main/org.keycloak.keycloak-themes-<VERSION>.jar
にある JAR ファイル内の theme/base/<THEME_TYPE>
ディレクトリーを参照してください。
手順
- テンプレートをベーステーマから独自のテーマにコピーします。
必要な変更を適用します。
たとえば、
mytheme
テーマのカスタムログインフォームを作成するには、themes/base/login/login.ftl
をthemes/mytheme/login
にコピーし、エディターで開きます。最初の行 (<#import …>) の後に、
<h1>HELLO WORLD!</h1>
を以下のように追加します。<#import "template.ftl" as layout> <h1>HELLO WORLD!</h1> ...
<#import "template.ftl" as layout> <h1>HELLO WORLD!</h1> ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 変更したテンプレートをバックアップします。Red Hat build of Keycloak の新しいバージョンにアップグレードする場合は、必要に応じて元のテンプレートに変更を適用できるようにカスタムテンプレートを更新する必要がある可能性があります。
3.4.10. 電子メール リンクのコピーリンクがクリップボードにコピーされました!
パスワードリカバリーメールなどのメールの件名および内容を編集するには、テーマの email
タイプにメッセージバンドルをを追加します。メールごとに 3 つのメッセージがあります。このサブジェクトの 1 つ。1 つはプレーンテキストの本文用に、もう 1 つは html 本文用です。
利用可能なすべてのメールを確認するには、themes/base/email/messages/messages_en.properties
を確認します。
たとえば、mytheme
テーマのパスワードリカバリーメールを変更するには、以下の内容で themes/mytheme/email/messages/messages_en.properties
を作成します。
passwordResetSubject=My password recovery passwordResetBody=Reset password link: {0} passwordResetBodyHtml=<a href="{0}">Reset password</a>
passwordResetSubject=My password recovery
passwordResetBody=Reset password link: {0}
passwordResetBodyHtml=<a href="{0}">Reset password</a>
3.5. テーマのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
テーマは、テーマディレクトリーを themes
にコピーして Red Hat build of Keycloak にデプロイするか、アーカイブとしてデプロイできます。開発中にテーマを themes
のディレクトリーにコピーできますが、実稼働環境では archive
の使用を検討してください。archive
を使用すると、特にクラスタリングなどにより Red Hat build of Keycloak のインスタンスが複数ある場合に、バージョン管理されたテーマのコピーを簡単に作成できます。
手順
- テーマをアーカイブとしてデプロイするには、テーマリソースを使用して JAR アーカイブを作成します。
META-INF/keycloak-themes.json
ファイルをアーカイブで利用可能なテーマをリスト表示するアーカイブに追加して、各テーマが提供するタイプを追加します。たとえば、
mytheme
テーマでは、以下の内容を含むmytheme.jar
を作成します。- META-INF/keycloak-themes.json
- theme/mytheme/login/theme.properties
- theme/mytheme/login/login.ftl
- theme/mytheme/login/resources/css/styles.css
- theme/mytheme/login/resources/img/image.png
- theme/mytheme/login/messages/messages_en.properties
theme/mytheme/email/messages/messages_en.properties
この場合、
META-INF/keycloak-themes.json
の内容は以下のようになります。Copy to Clipboard Copied! Toggle word wrap Toggle overflow 1 つのアーカイブに複数のテーマを含めることができ、各テーマでは 1 つまたは複数のタイプをサポートできます。
Red Hat build of Keycloak にアーカイブをデプロイするには、それを Red Hat build of Keycloak の providers/
ディレクトリーに追加し、サーバーがすでに実行されている場合は再起動します。
3.7. テーマリソース リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak でカスタムプロバイダーを実装するのであれば、多くの場合はテンプレート、リソース、およびメッセージバンドルをさらに追加する必要があります。
追加のテーマリソースを読み込む最も簡単な方法は、theme-resources/resources
の theme-resources/templates
リソース内に JAR を作成し、theme-resources/messages
のメッセージバンドルを作成することです。
テンプレートとリソースをさらに柔軟に読み込む方法が必要な場合には、ThemeResourceSPI で実現できます。ThemeResourceProviderFactory
および ThemeResourceProvider
を実装することで、テンプレートおよびリソースを読み込む方法を正確に決定できます。
3.8. ロケールセレクター リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、LocaleSelectorProvider
インターフェイスを実装する DefaultLocaleSelectorProvider
を使用してロケールが選択されます。国際化が無効になっている場合は、英語がデフォルト言語です。
国際化を有効にした場合、ロケールは サーバー管理ガイド に記載されているロジックに従って解決されます。
この動作は、LocaleSelectorProvider
および LocaleSelectorProviderFactory
を実装して、LocaleSelectorSPI
を介して変更できます。
LocaleSelectorProvider
インターフェイスには単一のメソッド resolveLocale
があり、RealmModel
および Null が可能な UserModel
を指定したロケールを返す必要があります。実際のリクエストは KeycloakSession#getContext
メソッドから利用できます。
カスタム実装は、デフォルトの動作の一部を再利用できるように DefaultLocaleSelectorProvider
を拡張できます。たとえば、Accept-Language
リクエストヘッダーを無視する場合、カスタム実装はデフォルトのプロバイダーを拡張し、その getAcceptLanguageHeaderLocale
をオーバーライドして Null 値を返すことができます。その結果、ロケールの選択はレルムのデフォルト言語にフォールバックします。
第4章 アイデンティティーブローカー API リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、親 IDP にログイン認証を委譲できます。典型的な例としては、Facebook や Google などのソーシャルプロバイダーを使用してユーザーがログインできるようにするケースがあります。既存のアカウントをブローカー化された IDP にリンクすることもできます。このセクションでは、アイデンティティーブローカーに関連するので、アプリケーションが使用する API についても一部説明します。
4.1. 外部 IDP トークンの取得 リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak を使用すると、外部 IDP を使用して認証プロセスからのトークンと応答を保存できます。これには、IDP の設定ページで Store Token
設定オプションを使用できます。
アプリケーションコードは、これらのトークンを取得し、追加のユーザー情報でプルしたり、外部 IDP でリクエストを安全に呼び出すことを行うことができます。たとえば、アプリケーションは Google トークンを使用して他の Google サービスおよび REST API で呼び出す場合があります。特定のアイデンティティープロバイダーのトークンを取得するには、以下のようにリクエストを送信する必要があります。
GET /realms/{realm}/broker/{provider_alias}/token HTTP/1.1 Host: localhost:8080 Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
GET /realms/{realm}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080
Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
アプリケーションは、Red Hat build of Keycloak で認証され、アクセストークンを受け取っている必要があります。このアクセストークンには、ブローカー
のクライアントレベルのロール read-token
を設定する必要があります。そのため、ユーザーにはこのロールのロールマッピングが必要で、クライアントアプリケーションにそのスコープ内にそのロールがなければなりません。この場合、Red Hat build of Keycloak で保護されたサービスにアクセスする場合には、ユーザー認証時に Red Hat build of Keycloak が発行するアクセストークンを送信する必要があります。ブローカー設定ページでは、Stored Tokens Readable
スイッチを有効にして、新たにインポートしたユーザーにこのロールを自動的に割り当てることができます。
これらの外部トークンは、プロバイダーを通じて再度ログインするか、クライアント起点のアカウントリンク API を使用することによって再確立できます。
4.2. クライアント起点のアカウントリンク リンクのコピーリンクがクリップボードにコピーされました!
アプリケーションによっては、Facebook などのソーシャルプロバイダーと統合しても、このようなソーシャルプロバイダー経由でログインするオプションを提供しないようにする場合もあります。Red Hat build of Keycloak は、アプリケーションが既存のユーザーアカウントを特定の外部 IDP にリンクするために使用できるブラウザーベースの API を提供します。これは、クライアント起点のアカウントリンクと呼ばれます。アカウントリンクは OIDC アプリケーションによってのみ開始できます。
アプリケーションがユーザーのブラウザーを Red Hat build of Keycloak サーバーの URL に転送する方法は、ユーザーのアカウントを特定の外部プロバイダー (Facebook など) にリンクするように要求することです。サーバーは外部プロバイダーでログインを開始します。ブラウザーは外部プロバイダーにログインし、サーバーにリダイレクトされます。サーバーはリンクを確立し、確認でアプリケーションにリダイレクトします。
このプロトコルを開始する前に、クライアントアプリケーションが満たさなければならない前提条件があります。
- 必要なアイデンティティープロバイダーは、管理コンソールでユーザーのレルムに対して設定して有効にする必要があります。
- ユーザーアカウントは、OIDC プロトコルを使用して既存のユーザーとしてログインしている必要があります。
-
ユーザーに
account.manage-account
またはaccount.manage-account-links
ロールマッピングが必要です。 - アプリケーションには、アクセストークン内で上記のロールのスコープが付与される必要があります。
- アプリケーションは、リダイレクト URL 生成にその情報を必要とするため、アクセストークンへのアクセスが必要です。
ログインを開始するには、アプリケーションは URL を作成し、ユーザーのブラウザーをこの URL にリダイレクトする必要があります。URL は以下のようになります。
/{auth-server-root}/realms/{realm}/broker/{provider}/link?client_id={id}&redirect_uri={uri}&nonce={nonce}&hash={hash}
/{auth-server-root}/realms/{realm}/broker/{provider}/link?client_id={id}&redirect_uri={uri}&nonce={nonce}&hash={hash}
以下は、各パスおよびクエリーパラメーターの説明です。
- provider
-
これは、管理コンソールの
Identity Provider
セクションで定義した外部 IDP のプロバイダーエイリアスです。 - client_id
- これは、アプリケーションの OIDC クライアント ID です。アプリケーションを管理コンソールでクライアントとして登録する場合は、このクライアント ID を指定する必要があります。
- redirect_uri
- これは、アカウントリンクの確立後にリダイレクトするアプリケーションのコールバック URL です。有効なクライアントのリダイレクト URI パターンである必要があります。つまり、管理コンソールでクライアント登録時に定義した有効な URL パターンのいずれかと一致する必要があります。
- nonce
- これは、アプリケーションが生成する必要のあるランダムな文字列です。
- hash
-
これは、Base64 URL でエンコードされたハッシュです。このハッシュは、Base64 URL で
nonce
+token.getSessionState()
+token.getIssuedFor()
+provider
の SHA_256 ハッシュをエンコードすることで生成されます。トークン変数は OIDC アクセストークンから取得されます。基本的に、アクセスするアイデンティティープロバイダーエイリアス、nonce、ユーザーセッション ID、クライアント ID、およびアイデンティティープロバイダーエイリアスを無作為にハッシュ化します。
以下は、アカウントリンクを確立するために URL を生成する Java Servlet コードの例になります。
このハッシュを含める理由認証サーバーで、クライアントアプリケーションが要求を開始したことを認識し、その他の不正なアプリが、特定のプロバイダーにリンクされるユーザーアカウントを無作為に要求しないように、ハッシュを含めます。認証サーバーは、最初にログイン時に設定された SSO クッキーをチェックしてユーザーがログインしているかどうかを確認します。その後、現在のログインに基づいてハッシュを再生成し、アプリケーションによって送信されるハッシュにマッチします。
アカウントのリンク後、認証サーバーは redirect_uri
にリダイレクトします。リンク要求の処理に問題がある場合は、認証サーバーが redirect_uri
にリダイレクトされない場合があります。ブラウザーは、アプリケーションにリダイレクトされるのではなく、エラーページで終了できます。エラー条件があり、認証サーバーがクライアントアプリケーションにリダイレクトするのに十分な安全でない場合には、追加の error
クエリーパラメーターが redirect_uri
に追加されます。
この API は、アプリケーションで確実に要求を開始されるようにしますが、この操作に対する CSRF 攻撃を完全に防ぐことはできません。このアプリケーションは、CSRF 攻撃ターゲットに対して自己防衛します。
4.2.1. 外部トークンのリフレッシュ リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーにログインして生成される外部トークン (つまり Facebook または GitHub トークン) を使用している場合は、アカウントリンク API を再度初期化してこのトークンを更新できます。
第5章 SPI (サービスプロバイダーインターフェイス) リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak は、カスタムコードを必要とせずにほとんどのユースケースに対応するように設計されていますが、カスタマイズ性も望まれています。そのため、Red Hat build of Keycloak には、独自プロバイダーの実装を可能にする数多くの SPI (サービスプロバイダーインターフェイス) があります。
5.1. SPI の実装 リンクのコピーリンクがクリップボードにコピーされました!
SPI を実装するには、その ProviderFactory および Provider インターフェイスを実装する必要があります。サービス設定ファイルも作成する必要があります。
たとえば、Theme Selector SPI を実装するには、ThemeSelectorProviderFactory および ThemeSelectorProvider を実装し、さらに META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
ファイルも指定する必要があります。
ThemeSelectorProviderFactory の例:
プロバイダーファクトリーの実装では、getId()
メソッドによって一意の ID を返すことを推奨します。ただし、以下の プロバイダーのオーバーライド セクションで説明するように、このルールには例外が存在する場合があります。
Red Hat build of Keycloak はプロバイダーファクトリーの単一のインスタンスを作成するので、複数の要求の状態を保存できます。プロバイダーのインスタンスは、各要求のファクトリーで create を呼び出すことで作成されるので、軽量オブジェクトでなければなりません。
ThemeSelectorProvider の例:
サービス設定ファイルの例 (META-INF/services/org.keycloak.theme.ThemeSelectorProviderFactory
):
org.acme.provider.MyThemeSelectorProviderFactory
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
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 void init(Config.Scope config) {
String themeName = config.get("theme");
}
必要に応じて、プロバイダーは他のプロバイダーを検索することもできます。以下に例を示します。
5.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()
を実装し、その順序をビルトインの実装よりも上位にすることを強く推奨します。
同じプロバイダー ID を持つ実装が複数ある場合、最上位の実装のみが Red Hat build of Keycloak ランタイムによって使用されます。
5.1.2. 管理コンソールで SPI 実装からの情報を表示 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーに関する追加情報を Red Hat build of Keycloak 管理者に表示すると便利な場合があります。プロバイダーのビルド時間情報 (現在インストールされているカスタムプロバイダーのバージョンなど)、プロバイダーの現在の設定 (プロバイダーが通信するリモートシステムの URL)、または一部の運用情報 (プロバイダーが対話するリモートシステムからの応答時間) を表示できます。Red Hat build of Keycloak 管理コンソールには、そのような情報を表示するサーバー情報ページがあります。
プロバイダーからの情報を表示するには、ProviderFactory
に org.keycloak.provider.ServerInfoAwareProviderFactory
インターフェイスを実装するだけで十分です。
前の例の MyThemeSelectorProviderFactory
の実装例:
5.2. 利用可能なプロバイダーの利用 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーの実装では、Red Hat build of Keycloak で利用可能な他のプロバイダーを使用できます。既存のプロバイダーは通常、KeycloakSession
を使用して取得できます。これは、セクション SPI の実装 で説明されているように、プロバイダーで利用できます。
Red Hat build of Keycloak には 2 つのプロバイダータイプがあります。
単一実装のプロバイダータイプ - Red Hat build of Keycloak ランタイムで、1 つのプロバイダータイプのみアクティブに実装できます。
たとえば
HostnameProvider
は、Red Hat build of Keycloak で使用されるホスト名を指定し、そのホスト名が Red Hat build of Keycloak サーバー全体で共有されます。そのため、Red Hat build of Keycloak サーバーでアクティブになるこのプロバイダーの実装は 1 つだけです。サーバーランタイムに複数のプロバイダー実装が利用できる場合は、それらのいずれかをデフォルトとして指定する必要があります。
たとえば、以下のようなものです。
bin/kc.[sh|bat] build --spi-hostname-provider=default
bin/kc.[sh|bat] build --spi-hostname-provider=default
default-provider
の値として使用される default
は、特定のプロバイダーファクトリー実装の ProviderFactory.getId()
が返す ID と一致する必要があります。コードでは、keycloakSession.getProvider(HostnameProvider.class)
のようにプロバイダーを取得します。
複数実装のプロバイダータイプ - Red Hat build of Keycloak ランタイムで複数の実装を利用し、一緒に動作させることができるプロバイダータイプです。
たとえば、
EventListener
プロバイダーは、利用可能で登録された複数の実装を持つことができます。これは、特定のイベントがすべてのリスナー (jboss-logging、sysout など) に送信できることを意味します。コードでは、たとえばsession.getProvider(EventListener.class, "jboss-logging")
のように、プロバイダーの指定したインスタンスを取得することができます。前述のように、このプロバイダータイプのインスタンスは複数存在する可能性があるため、第 2 引数にプロバイダーのprovider_id
を指定する必要があります。プロバイダー ID は、特定のプロバイダーファクトリー実装の
ProviderFactory.getId()
が返す ID と一致する必要があります。プロバイダーの種類によっては、第 2 引数にComponentModel
を指定することで取得できるものもありますし、KeycloakSessionFactory
を指定しなければならないものもあります (Authenticator
など)。将来的に非推奨となる可能性があるため、この方法で独自のプロバイダーを実装することは推奨できません。
5.3. プロバイダー実装の登録 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーは、JAR ファイルを providers
ディレクトリーにコピーするだけでサーバーに登録されます。
Keycloak が提供していない別の依存関係が追加で必要な場合は、それを providers
ディレクトリーにコピーします。
新しいプロバイダーまたは依存関係を登録した後、Keycloak を、最適化なしの start コマンドまたは kc.[sh|bat] build
コマンドで再構築する必要があります。
プロバイダーの JAR は、分離されたクラスローダーにロードされないため、組み込みのリソースまたはクラスと、競合するリソースまたはクラスをプロバイダーの JAR に含めないでください。特に、application.properties ファイルを含めるか、commons-lang3 依存関係をオーバーライドすると、プロバイダーの JAR が削除された場合に自動ビルドが失敗します。競合するクラスが含まれている場合、サーバーの起動ログにパッケージ分離の警告が表示されることがあります。すべての組み込みの lib jar がパッケージ分離の警告ロジックによってチェックされるわけではありません。そのため、推移的な依存関係をバンドルまたは含める前に、lib ディレクトリーの JAR をチェックする必要があります。競合が発生した場合は、問題のあるクラスを削除するか再パッケージ化することで解決できます。
競合するリソースファイルがあっても、警告は表示されません。JAR のリソースファイルのパス名が、そのプロバイダーに固有のものであることを確認してください。または、次のような方法で、"install root"/lib/lib/main
ディレクトリー配下の JAR の内容に some.file
が存在するかどうかを確認してください。
find . -type f -name "*.jar" -exec unzip -l {} \; | grep some.file
find . -type f -name "*.jar" -exec unzip -l {} \; | grep some.file
削除されたプロバイダーの JAR に関連する NoSuchFileException
エラーが原因でサーバーが起動しない場合は、次を実行します。
./kc.sh -Dquarkus.launch.rebuild=true
./kc.sh -Dquarkus.launch.rebuild=true
これにより、Quarkus がクラスローディング関連のインデックスファイルを強制的に再構築します。その後、最適化なしの start または build を例外を出さずに実行できるはずです。
5.3.1. プロバイダーの無効化 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーを無効化するには、プロバイダーの enabled 属性を false に設定します。たとえば、Infinispan ユーザーキャッシュプロバイダーを無効にするには、以下を使用します。
bin/kc.[sh|bat] build --spi-user-cache-infinispan-enabled=false
bin/kc.[sh|bat] build --spi-user-cache-infinispan-enabled=false
5.4. JavaScript プロバイダー リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak には、管理者が特定の機能をカスタマイズできるように、ランタイム時にスクリプトを実行する機能があります。
- オーセンティケーター
- JavaScript ポリシー
- OpenID Connect Protocol Mapper
- SAML プロトコルマッパー
5.4.1. オーセンティケーター リンクのコピーリンクがクリップボードにコピーされました!
認証スクリプトは、Authenticator#action(AuthenticationFlowContext)
から呼び出される Authenticator#authenticate(AuthenticationFlowContext)
action(..)
から呼び出される authenticate(..)
関数を少なくとも 1 つ提供する必要があります。
カスタム Authenticator
は、最低でも authenticate(..)
関数を提供する必要があります。コード内で javax.script.Bindings
スクリプトを使用できます。
script
-
スクリプトメタデータにアクセスするための
ScriptModel
realm
-
RealmModel
user
-
現在の
UserModel
。user
を使用できるのは、別のオーセンティケーターがユーザーアイデンティティーの確立に成功し、ユーザーを認証セッションに設定した後にトリガーされるように、スクリプトオーセンティケーターが認証フロー内で設定されている場合です。 session
-
アクティブな
KeycloakSession
authenticationSession
-
現在の
AuthenticationSessionModel
httpRequest
-
the current
org.jboss.resteasy.spi.HttpRequest
LOG
-
ScriptBasedAuthenticator
にスコープ指定されたorg.jboss.logging.Logger
authenticate(context)
action(context)
関数に渡される context
引数から追加のコンテキスト情報を抽出できます。
5.4.1.1. スクリプトオーセンティケーターを追加する場所 リンクのコピーリンクがクリップボードにコピーされました!
スクリプトオーセンティケーターの使用方法としては、認証の最後にいくつかのチェックを実行することが考えられます。スクリプトオーセンティケーターを (たとえば、アイデンティティー Cookie による SSO 再認証中であっても) 常にトリガーする場合、認証フローの最後にスクリプトオーセンティケーターを REQUIRED として追加し、既存のスクリプトオーセンティケーターを別の REQUIRED の認証サブフローにカプセル化する必要がある場合があります。これが必要なのは、REQUIRED と ALTERNATIVE の実行を同じレベルにすることができないためです。たとえば、認証フロー設定は次のようになります。
- User-authentication-subflow REQUIRED -- Cookie ALTERNATIVE -- Identity-provider-redirect ALTERNATIVE ... - Your-Script-Authenticator REQUIRED
- User-authentication-subflow REQUIRED
-- Cookie ALTERNATIVE
-- Identity-provider-redirect ALTERNATIVE
...
- Your-Script-Authenticator REQUIRED
5.4.2. OpenID Connect Protocol Mapper リンクのコピーリンクがクリップボードにコピーされました!
OpenID Connect Protocol Mapper スクリプトは、ID トークンやアクセストークンの内容を変更できる JavaScript スクリプトです。
コード内で javax.script.Bindings
スクリプトを使用できます。
user
-
現在の
UserModel
realm
-
RealmModel
token
-
現在の
IDToken
。ID トークン用にマッパーが設定されている場合にのみ使用できます。 tokenResponse
-
現在の
AccessTokenResponse
。アクセストークン用にマッパーが設定されている場合にのみ使用できます。 userSession
-
アクティブな
UserSessionModel
keycloakSession
-
アクティブな
KeycloakSession
スクリプトのエクスポートが、トークンクレームの値として使用されます。
上記のスクリプトを使用すると、認証リクエストから user_input
を取得できます。これは、マッパーで設定された Token Claim Name
にマッピングするために使用できます。
5.4.3. スクリプトで JAR を作成してデプロイ リンクのコピーリンクがクリップボードにコピーされました!
JAR ファイルは、.jar
拡張子を持つ通常の ZIP ファイルです。
Red Hat build of Keycloak でスクリプトを利用できるようにするには、サーバーにスクリプトをデプロイする必要があります。そのため、以下の構造で JAR
ファイルを作成します。
META-INF/keycloak-scripts.json my-script-authenticator.js my-script-policy.js my-script-mapper.js
META-INF/keycloak-scripts.json
my-script-authenticator.js
my-script-policy.js
my-script-mapper.js
META-INF/keycloak-scripts.json
は、デプロイするスクリプトに関するメタデータ情報を提供するファイル記述子です。これは、次の構造が含まれる JSON ファイルです。
このファイルは、デプロイする別のタイプのスクリプトプロバイダーを参照する必要があります。
authenticators
OpenID Connect Script Authenticator 用。同じ JAR ファイルに 1 つまたは複数のオーセンティケーターを設定できます。
policies
Red Hat build of Keycloak Authorization Services を使用する場合の JavaScript ポリシー用。同じ JAR ファイルに 1 つまたは複数のポリシーを設定できます。
mappers
OpenID Connect Script Protocol Mapper 用。同じ JAR ファイルに 1 つまたは複数のマッパーを設定できます。
saml-mappers
SAML Script Protocol Mapper 用。同じ JAR ファイルに 1 つまたは複数のマッパーを設定できます。
JAR
ファイルのスクリプトファイルごとに、スクリプトファイルを特定のプロバイダータイプにマッピングする META-INF/keycloak-scripts.json
に対応するエントリーが必要です。そのためには、各エントリーに以下のプロパティーを指定する必要があります。
name
Red Hat build of Keycloak 管理コンソールでのスクリプト表示に使用するための分かりやすい名前。指定がない場合は、代わりにスクリプトファイルを使用します。
description
スクリプトファイルの意図をより適切に説明する任意のテキスト
fileName
スクリプトファイルの名前。このプロパティーは 必須 であり、JAR 内のファイルにマップする必要があります。
5.4.4. スクリプト JAR のデプロイ リンクのコピーリンクがクリップボードにコピーされました!
記述子とデプロイするスクリプトを含む JAR ファイルを作成したら、その JAR を Red Hat build of Keycloak の providers/
ディレクトリーにコピーして、bin/kc.[sh|bat] build
を実行します。scripts
機能を有効にする必要もあることに注意してください。
5.5. 利用可能な SPI リンクのコピーリンクがクリップボードにコピーされました!
実行時に利用可能なすべての SPI のリストを表示する場合は、管理コンソール セクションで説明されているように、管理コンソールの Server Info
ページを確認できます。
第6章 ユーザーストレージ 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 クイックスタートの簡単な説明を示しています。
名前 | 説明 |
---|---|
EJB と JPA を使用してユーザーストレージプロバイダーを実装する方法を説明しています。 | |
ユーザー名とパスワードのキーペアが含まれる単純なプロパティーファイルを使用して、ユーザーストレージプロバイダーを実装する方法を説明しています。 |
6.1. プロバイダーインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
User Storage SPI の実装を構築する場合は、プロバイダークラスとプロバイダーファクトリーを定義する必要があります。プロバイダークラスインスタンスは、プロバイダーファクトリーによってトランザクションごとに作成されます。プロバイダークラスは、ユーザー検索やその他のユーザー操作で負荷が大きい作業をすべて行います。org.keycloak.storage.UserStorageProvider
インターフェイスを実装する必要があります。
UserStorageProvider
インターフェイスはほんのわずかであると思われるかもしれません。この章では後で、ユーザー統合のサポート向けにプロバイダーが実装する可能性のあるさまざまなインターフェイスが他にあることを説明します。
UserStorageProvider
インスタンスは、トランザクションごとに 1 度作成されます。トランザクションが完了すると、UserStorageProvider.close()
メソッドが呼び出され、インスタンスはガベージコレクションされます。インスタンスはプロバイダーファクトリーによって作成されます。プロバイダーファクトリーは org.keycloak.storage.UserStorageProviderFactory
インターフェイスを実装します。
プロバイダーファクトリークラスは、UserStorageProviderFactory
を実装する際に、具体的なプロバイダークラスをテンプレートパラメーターとして指定する必要があります。これはランタイムがこのクラスをイントロスペクションしてその機能 (実装する他のインターフェイス) をスキャンするため必要です。たとえば、プロバイダークラスの名前が FileProvider
の場合、ファクトリークラスは以下のようになります。
getId()
メソッドは、User Storage プロバイダーの名前を返します。この ID は、特定のレルムのプロバイダーを有効にする際に管理コンソールのユーザーフェデレーションページに表示されます。
create()
メソッドは、プロバイダークラスのインスタンスを割り当てます。org.keycloak.models.KeycloakSession
パラメーターを取ります。このオブジェクトは、その他の情報およびメタデータを検索し、ランタイム内の他のコンポーネントへのアクセスを提供するために使用できます。ComponentModel
パラメーターは、プロバイダーが特定のレルム内でどのように有効および設定されたかを表します。これには、有効化されたプロバイダーのインスタンス ID と、管理コンソールで有効にした場合に指定できる設定が含まれます。
UserStorageProviderFactory
には他の機能があり、この後、この章で取り上げます。
6.2. プロバイダー機能のインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
UserStorageProvider
インターフェイスを詳しく調べると、ユーザーを検索または管理するための方法を定義しないことが分かります。これらの方法は、外部ユーザーストアが提供および実行可能な機能の範囲に応じて、実際に他の 機能インターフェイス で定義されます。たとえば、外部ストアの一部は読み取り専用で、単純なクエリーおよび認証情報の検証のみを実行できます。可能な機能の 機能インターフェイス を実装することのみが必要になります。これらのインターフェイスを実装することができます。
SPI | 説明 |
---|---|
| この外部ストアのユーザーを使用してログインできるようにする場合には、このインターフェイスが必要です。大半 (またはすべて) プロバイダーはこのインターフェイスを実装します。 |
| 1 つ以上のユーザーの特定に使用する複雑なクエリーを定義します。管理コンソールからユーザーを表示および管理する場合は、このインターフェイスを実装する必要があります。 |
| プロバイダーがクエリーのカウントをサポートしている場合は、このインターフェイスを実装します。 |
|
このインターフェイスは、 |
| プロバイダーがユーザーの追加および削除に対応している場合は、このインターフェイスを実装します。 |
| プロバイダーがユーザーセットの一括更新をサポートする場合は、このインターフェイスを実装します。 |
| プロバイダーが 1 つ以上の異なる認証情報タイプを検証できる場合は、このインターフェイスを実装します (たとえば、プロバイダーがパスワードを検証できる場合など)。 |
| プロバイダーが 1 つ以上の異なる認証情報タイプの更新をサポートする場合は、このインターフェイスを実装します。 |
6.3. モデルインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
機能 インターフェイス で定義されるメソッドのほとんどは、ユーザーの表現を返すか、渡されます。これらの表現は、org.keycloak.models.UserModel
インターフェイスで定義されます。アプリケーション開発者は、このインターフェイスを実装する必要があります。Red Hat build of Keycloak が使用する外部ユーザーストアとユーザーメタモデル間でマッピングを行います。
UserModel
実装は、ユーザー名、名前、電子メール、ロール、グループマッピング、その他の任意の属性などのユーザーに関するメタデータの読み取りおよび更新へのアクセスを提供します。
org.keycloak.models
パッケージには、Red Hat build of Keycloak メタモデルの他の部分を表す他のモデルクラスがあります (RealmModel
、RoleModel
、GroupModel
、および ClientModel
)。
6.3.1. ストレージ ID リンクのコピーリンクがクリップボードにコピーされました!
UserModel
の重要なメソッドの 1 つとして、getId()
メソッドがあります。UserModel
の開発者は、ユーザー ID 形式を認識する必要があります。形式は以下のとおりです。
"f:" + component id + ":" + external id
"f:" + component id + ":" + external id
Red Hat build of Keycloak ランタイムは、多くの場合、ユーザー ID でユーザーを検索する必要があります。ユーザー ID には十分な情報が含まれているため、ランタイムは、システム内のすべての UserStorageProvider
を紹介して、ユーザーを見つける必要はありません。
コンポーネント ID は、ComponentModel.getId()
から返される ID です。ComponentModel
はプロバイダークラスの作成時にパラメーターとして渡され、そこから取得できるようにします。外部 ID は、プロバイダークラスが外部ストアでのユーザー検索に必要な情報です。通常これはユーザー名または uid です。たとえば、以下のようになります。
f:332a234e31234:wburke
f:332a234e31234:wburke
ランタイムが ID でルックアップを行う場合、ID はコンポーネント ID を取得するよう解析されます。コンポーネント ID は、ユーザーの読み込みに最初に使用された UserStorageProvider
を見つけるために使用されます。その後、そのプロバイダーには ID が渡されます。プロバイダーが再び ID を解析して外部 ID を取得し、外部ユーザーストレージでのユーザー検索に使用されます。
6.4. パッケージおよびデプロイメント リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak がプロバイダーを認識できるようにするには、ファイルを JAR (META-INF/services/org.keycloak.storage.UserStorageProviderFactory
) に追加する必要があります。このファイルには、UserStorageProviderFactory
実装の完全修飾クラス名の行区切りリストが含まれている必要があります。
org.keycloak.examples.federation.properties.ClasspathPropertiesStorageFactory org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
org.keycloak.examples.federation.properties.ClasspathPropertiesStorageFactory
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
この jar をデプロイするには、providers/
ディレクトリーにコピーしてから bin/kc.[sh|bat] build
を実行します。
6.5. シンプルな読み取り専用、ルックアップの例 リンクのコピーリンクがクリップボードにコピーされました!
User Storage SPI を実装する際の基本事項について、簡単な例を追って説明します。この章では、簡単なプロパティーファイルでユーザーを検索する簡単な UserStorageProvider
の実装を説明します。プロパティーファイルにはユーザー名とパスワードの定義が含まれ、クラスパス上の特定の場所にハードコーディングされます。プロバイダーは、ID およびユーザー名でユーザーを検索でき、パスワードを検証することもできます。このプロバイダーから発信されるユーザーは読み取り専用です。
6.5.1. プロバイダークラス リンクのコピーリンクがクリップボードにコピーされました!
最初に説明するのは UserStorageProvider
クラスです。
プロバイダークラス PropertyFileUserStorageProvider
は多くのインターフェイスを実装します。SPI のベース要件であるように UserStorageProvider
を実装します。このプロバイダーが保存したユーザーでログインできるため、UserLookupProvider
インターフェイスを実装します。ログイン画面で入力されたパスワードを検証する必要があるため、CredentialInputValidator
インターフェイスを実装します。プロパティーファイルは読み取り専用です。ユーザーがパスワードを更新しようとするとエラー条件を投稿するため、CredentialInputUpdater
を実装します。
このプロバイダークラスのコンストラクターは KeycloakSession
、ComponentModel
、およびプロパティーファイルへの参照を保存します。後ほどこれらすべてを使用します。また、読み込んだユーザーのマップがあることにも注意してください。ユーザーを特定すると、このマップに保存し、同じトランザクションで再度ユーザーが作成されないようにします。多数のプロバイダーがこれを行う必要があるので (JPA と統合しているプロバイダー)、この慣習は適切です。また、プロバイダークラスインスタンスはトランザクションごとに 1 度作成され、トランザクションの完了後に閉じられることにも注意してください。
6.5.1.1. UserLookupProvider 実装 リンクのコピーリンクがクリップボードにコピーされました!
getUserByUsername()
メソッドは、ユーザーがログインすると Red Hat build of Keycloak ログインページにより呼び出されます。実装では最初に loadedUsers
マップを確認し、ユーザーがこのトランザクション内にすでに読み込まれているかどうかを確認します。読み込まれていない場合は、ユーザー名のプロパティーファイルを探します。UserModel
の実装を作成する場合は、将来のの参照のために loadedUsers
に保存し、このインスタンスを返します。
createAdapter()
メソッドはヘルパークラス org.keycloak.storage.adapter.AbstractUserAdapter
を使用します。これにより、UserModel
のベース実装が提供されます。外部 ID としてユーザーのユーザー名を使用して、必要なストレージ ID 形式に基づいてユーザー ID を自動的に生成します。
"f:" + component id + ":" + username
"f:" + component id + ":" + username
AbstractUserAdapter
のすべての get メソッドは、Null または空のコレクションを返します。ただし、ロールマッピングおよびグループマッピングを返すメソッドは、すべてのユーザーのレルムに設定されたデフォルトのロールおよびグループを返します。AbstractUserAdapter
のすべてのセットメソッドは、org.keycloak.storage.ReadOnlyException
を発生させます。そのため、管理コンソールでユーザーを変更しようとすると、エラーが発生します。
getUserById()
メソッドは、org.keycloak.storage.StorageId
ヘルパークラスを使用して id
パラメーターを解析します。StorageId.getExternalId()
メソッドが呼び出され、id
パラメーターに埋め込まれたユーザー名を取得します。その後、メソッドは getUserByUsername()
に委譲します。
メールは保存されないため、getUserByEmail()
メソッドは null を返します。
6.5.1.2. CredentialInputValidator 実装 リンクのコピーリンクがクリップボードにコピーされました!
次に、CredentialInputValidator
のメソッド実装を確認します。
isConfiguredFor()
メソッドはランタイムによって呼び出され、特定の認証情報タイプがユーザーに設定されているかどうかを判断します。この方法は、パスワードがユーザーに設定されていることを確認します。
supportsCredentialType()
メソッドは、特定の認証情報タイプに対して検証がサポートされるかどうかを返します。認証情報のタイプが password
であるかを確認します。
isValid()
メソッドはパスワードを検証します。CredentialInput
パラメーターは、すべての認証情報タイプの抽象インターフェイスにすぎません。認証情報タイプもサポートし、UserCredentialModel
のインスタンスであることを確認します。ユーザーがログインページでログインすると、UserCredentialModel
のインスタンスに入力されたパスワード入力のプレーンテキストが追加されます。isValid()
メソッドは、この値をプロパティーファイルに保存されているプレーンテキストのパスワードと照合します。戻り値 true
はパスワードが有効であることを意味します。
6.5.1.3. CredentialInputUpdater 実装 リンクのコピーリンクがクリップボードにコピーされました!
前述したように、CredentialInputUpdater
インターフェイスは、ユーザーパスワードの変更を禁止するためだけに実装します。そうしなければ Red Hat build of Keycloak のローカルストレージでランタイムによりパスワードを上書きできるため、このような対応が必要です。この章の後半で詳しく説明します。
updateCredential()
メソッドは、認証情報タイプがパスワードであるかどうかを確認します。存在する場合は、ReadOnlyException
が発生します。
6.5.2. プロバイダーファクトリーの実装 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダークラスが完成したので、プロバイダーファクトリークラスを見ていきます。
最初に UserStorageProviderFactory
クラスを実装する場合は、具体的なプロバイダークラス実装をテンプレートパラメーターとして渡す必要があります。ここで、以前に定義したプロバイダークラス (PropertyFileUserStorageProvider
) を指定します。
template パラメーターを指定しない場合には、プロバイダーは機能しません。ランタイムはクラスのイントロスペクションを実行し、プロバイダーが実装する 機能インターフェイス を判別します。
getId()
メソッドはランタイムのファクトリーを識別し、レルムのユーザーストレージプロバイダーを有効にする場合も管理コンソールに表示される文字列になります。
6.5.2.1. 初期化 リンクのコピーリンクがクリップボードにコピーされました!
UserStorageProviderFactory
インターフェイスには、実装できる任意の init()
メソッドがあります。Red Hat build of Keycloak の起動時に、各プロバイダーファクトリーのインスタンスが 1 つだけ作成されます。また、システムの起動時に、これらの各ファクトリーのインスタンスでも init()
メソッドが呼び出されます。同様に実装できる postInit()
メソッドも実装できます。各ファクトリーの init()
メソッドが呼び出されると、postInit()
メソッドが呼び出されます。
init()
メソッド実装では、クラスパスからユーザー宣言が含まれるプロパティーファイルを見つけます。次に properties
フィールドを、そこに保存されたユーザー名とパスワードの組み合わせでロードします。
Config.Scope
パラメーターは、サーバー設定を介して設定されるファクトリー設定です。
たとえば、次の引数を使用してサーバーを実行します。
kc.[sh|bat] start --spi-storage-readonly-property-file-path=/other-users.properties
kc.[sh|bat] start --spi-storage-readonly-property-file-path=/other-users.properties
ハードコーディングするのではなく、ユーザープロパティーファイルのクラスパスを指定できます。次に、PropertyFileUserStorageProviderFactory.init()
で設定を取得できます。
6.5.2.2. 作成方法 リンクのコピーリンクがクリップボードにコピーされました!
プロバイダーファクトリー作成における最後の手順は create()
メソッドです。
@Override public PropertyFileUserStorageProvider create(KeycloakSession session, ComponentModel model) { return new PropertyFileUserStorageProvider(session, model, properties); }
@Override
public PropertyFileUserStorageProvider create(KeycloakSession session, ComponentModel model) {
return new PropertyFileUserStorageProvider(session, model, properties);
}
PropertyFileUserStorageProvider
クラスを割り当てるだけです。この create メソッドはトランザクションごとに 1 回呼び出されます。
6.5.3. パッケージおよびデプロイメント リンクのコピーリンクがクリップボードにコピーされました!
プロバイダー実装のクラスファイルは jar に配置する必要があります。また、META-INF/services/org.keycloak.storage.UserStorageProviderFactory
ファイルでプロバイダーファクトリークラスを宣言する必要があります。
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
この jar をデプロイするには、providers/
ディレクトリーにコピーしてから bin/kc.[sh|bat] build
を実行します。
6.5.4. 管理コンソールでのプロバイダーの有効化 リンクのコピーリンクがクリップボードにコピーされました!
管理コンソールの User Federation ページで、レルムごとにユーザーストレージプロバイダーを有効にします。
ユーザーフェデレーション
手順
readonly-property-file
リストから作成したプロバイダーを選択します。プロバイダーの設定ページが表示されます。
設定するものがないため、Save をクリックします。
設定されたプロバイダー
User Federation のメインページに戻ります。
これで、プロバイダーがリスト表示されます。
ユーザーフェデレーション
これで、users.properties
ファイルで宣言されたユーザーでログインできるようになります。このユーザーは、ログイン後にのみアカウントページを表示できます。
6.6. 設定方法 リンクのコピーリンクがクリップボードにコピーされました!
PropertyFileUserStorageProvider
の例は少々工夫されています。これは、プロバイダーの jar に組み込まれているプロパティーファイルにハードコーディングされているので、あまり便利ではありません。プロバイダーのインスタンスごとにこのファイルの場所を設定する場合があります。言い換えると、このプロバイダーを複数の異なるレルムで複数回再利用したり、全く異なるユーザープロパティーファイルを参照する場合などです。また、管理コンソール UI 内でこの設定を実行する必要があります。
UserStorageProviderFactory
には、プロバイダー設定を実装できる追加のメソッドがあります。プロバイダーごとに設定する変数を記述すると、管理コンソールは自動的に一般的な入力ページをレンダリングしてこの設定を収集します。実装されている場合、コールバックメソッドは、設定が保存される前、プロバイダーが初めて作成されるとき、および更新されるときにも検証を行います。UserStorageProviderFactory
は、org.keycloak.component.ComponentFactory
インターフェイスからこれらのメソッドを継承します。
ComponentFactory.getConfigProperties()
メソッドは、org.keycloak.provider.ProviderConfigProperty
インスタンスのリストを返します。これらのインスタンスは、プロバイダーの各設定変数のレンダリングおよび保存に必要なメタデータを宣言します。
6.6.1. 設定例 リンクのコピーリンクがクリップボードにコピーされました!
PropertyFileUserStorageProviderFactory
の例を拡張して、プロバイダーインスタンスをディスク上の特定のファイルを指定できるようにします。
PropertyFileUserStorageProviderFactory
ProviderConfigurationBuilder
クラスは、設定プロパティーのリストを作成するためのヘルパークラスです。ここでは、String タイプである path
という名前の変数を指定します。このプロバイダーの管理コンソール設定ページでは、この設定変数は Path
としてラベル付けされ、デフォルト値は ${jboss.server.config.dir}/example-users.properties
です。この設定オプションのツールチップにカーソルを合わせると、ヘルプテキスト (File path to properties file (プロパティーファイルへのファイルパス)
) が表示されます。
次に、このファイルがディスクに存在することを確認します。有効なユーザープロパティーファイルを参照しない限り、レルムでこのプロバイダーのインスタンスを有効するべきではありません。これを実行するには、validateConfiguration()
メソッドを実装します。
validateConfiguration()
メソッドは、ComponentModel
から設定変数を提供して、そのファイルがディスク上に存在するかどうかを確認します。org.keycloak.common.util.EnvUtil.replace()
メソッドを使用していることに注目してください。このメソッドを使用すると、${}
を含む文字列で、その値がシステムプロパティー値に置き換えられます。${jboss.server.config.dir}
文字列はサーバーの conf/
ディレクトリーに対応するものであり、この例では非常に役立ちます。
次に、古い init()
メソッドを削除します。ユーザープロパティーファイルはプロバイダーインスタンスごとに一意であるため、これを行います。このロジックは create()
メソッドに移動します。
全トランザクションでユーザープロパティーファイル全体をディスクから読み取るので、当然このロジックは効率的ではありませんが、今回の例で、設定変数をフックする方法をシンプルに説明できたかと思います。
6.6.2. 管理コンソールでのプロバイダーの設定 リンクのコピーリンクがクリップボードにコピーされました!
設定が有効になったため、管理コンソールでプロバイダーを設定する際に path
変数を設定できます。
6.7. ユーザーおよびクエリー機能インターフェイスの追加/削除 リンクのコピーリンクがクリップボードにコピーされました!
今回の例で対応していない内容の 1 つとして、ユーザーやパスワードの追加および削除を可能にする操作です。また、この例で定義されたユーザーは、管理コンソールでクエリーや表示ができません。このような拡張機能を追加するには、example プロバイダーが UserQueryMethodsProvider
インターフェイス (または UserQueryProvider
) および UserRegistrationProvider
インターフェイスを実装する必要があります。
6.7.1. UserRegistrationProvider の実装 リンクのコピーリンクがクリップボードにコピーされました!
この手順を使用して、特定のストアからユーザーの追加および削除を実装します。その場合、最初にプロパティーファイルをディスクに保存する必要があります。
PropertyFileUserStorageProvider
次に、addUser()
メソッドおよび removeUser()
メソッドの実装が簡単になります。
PropertyFileUserStorageProvider
ユーザーを追加する場合は、プロパティーマップのパスワード値を UNSET_PASSWORD
に設定することに注意してください。これを実行するのは、プロパティー値に null 値を指定できないためです。また、これを反映するように CredentialInputValidator
メソッドを変更する必要もあります。
プロバイダーが UserRegistrationProvider
インターフェイスを実装している場合は、addUser()
メソッドが呼び出されます。プロバイダーにユーザーの追加をオフにする設定スイッチがある場合は、このメソッドから null
を返すとこのプロバイダーが飛ばされ、次のプロバイダーを呼び出します。
PropertyFileUserStorageProvider
プロパティーファイルを保存できるようになったため、パスワードの更新を許可しても問題ありません。
PropertyFileUserStorageProvider
パスワードの無効化も実装できるようになりました。
PropertyFileUserStorageProvider
これらのメソッドを実装すると、管理コンソールでユーザーのパスワードを変更および無効化できるようになりました。
6.7.2. UserQueryProvider の実装 リンクのコピーリンクがクリップボードにコピーされました!
UserQueryProvider
は、UserQueryMethodsProvider
と UserCountMethodsProvider
を組み合わせたものです。UserQueryMethodsProvider
を実装しないと、管理コンソールは example プロバイダーによって読み込まれたユーザーを表示および管理できません。このインターフェイスの実装を見てみましょう。
PropertyFileUserStorageProvider
searchForUserStream()
の最初の宣言は、String
パラメーターを受け取ります。この例では、パラメーターは検索に使用するユーザー名を表します。この文字列は部分文字列にすることができます。そのため、検索を行う際には String.contains()
メソッドを選択します。すべてのユーザーのリストを要求することを示すために *
を使用していることに注目してください。このメソッドはプロパティーファイルのキーセットを繰り返し処理し、getUserByUsername()
にユーザーを読み込みます。firstResult
パラメーターおよび maxResults
パラメーターに基づいてこの呼び出しにインデックス化していることに留意してください。外部ストアがページネーションをサポートしない場合には、同様のロジックを実行する必要があります。
PropertyFileUserStorageProvider
Map
パラメーターを取る searchForUserStream()
メソッドは、姓名、ユーザー名、およびメールに基づいてユーザーを検索できます。ユーザー名のみが保存されるため、Map
パラメーターに username
属性が含まれていない場合を除き、検索はユーザー名のみに基づいて行われます。この場合、すべてのユーザーが返されます。このような場合、searchForUserStream(realm, search, firstResult, maxResults)
が使用されます。
PropertyFileUserStorageProvider
グループまたは属性は保存されないため、他のメソッドは空のストリームを返します。
6.8. 外部ストレージの拡張 リンクのコピーリンクがクリップボードにコピーされました!
PropertyFileUserStorageProvider
例は実際に制限されています。プロパティーファイルに保存されているユーザーでログインできますが、それ以外にできることはほぼありません。このプロバイダーがロードしたユーザーが、特定のアプリケーションに完全にアクセスできるように、特別なロールまたはグループマッピングが必要な場合は、これらのユーザーに別のロールマッピングを追加する方法はありません。また、電子メール、名、姓などの重要な属性を変更したり、追加したりすることはできません。
このような状況では、Red Hat build of Keycloak のデータベースに追加情報を保存して外部ストアを拡張できます。これはフェデレーテッドユーザーストレージと呼ばれ、org.keycloak.storage.federated.UserFederatedStorageProvider
クラス内にカプセル化されます。
UserFederatedStorageProvider
UserFederatedStorageProvider
インスタンスは、UserStorageUtil.userFederatedStorage(KeycloakSession)
メソッドで利用できます。これには、あらゆる種類のメソッドがあり、属性、グループおよびロールマッピング、さまざまな認証情報タイプ、および必要なアクションを保存できます。外部ストアのデータモデルが、Red Hat build of Keycloak 機能セットに完全対応していない場合、このサービスを使用することで対応できます。
Red Hat build of Keycloak にはヘルパークラス org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage
が同梱されています。このクラスは、ユーザー名の get/set を除くすべての UserModel
メソッドを、ユーザーフェデレーションストレージに委譲します。外部ストレージ表現に委譲するのに必要なメソッドを上書きします。上書きする保護メソッドが少ないため、このクラスの javadoc を参照することを強く推奨します。具体的には、グループメンバーシップおよびロールマッピング関連です。
6.8.1. 拡張例 リンクのコピーリンクがクリップボードにコピーされました!
PropertyFileUserStorageProvider
の例では、AbstractUserAdapterFederatedStorage
を使用するためにプロバイダーに簡単な変更が必要になります。
PropertyFileUserStorageProvider
代わりに、AbstractUserAdapterFederatedStorage
の匿名クラス実装を定義します。setUsername()
メソッドはプロパティーファイルを変更し、これを保存します。
6.9. 実装ストラテジーのインポート リンクのコピーリンクがクリップボードにコピーされました!
ユーザーストレージプロバイダーを実装する場合は、別のストラテジーを使用できます。ユーザーフェデレーションストレージを使用する代わりに、Red Hat build of Keycloak のビルトインユーザーデータベースでユーザーをローカルで作成し、外部ストアからこのローカルコピーに属性をコピーします。この方法には多くの利点があります。
- 基本的に、Red Hat build of Keycloak は外部ストアの永続ユーザーキャッシュになります。ユーザーがインポートされると、外部ストアに到達できなくなるため、負荷はなくなります。
- 公式ユーザーストアとして Red Hat build of Keycloak に移行し、古い外部ストアを非推奨にする場合は、アプリケーションを徐々に移行して Red Hat build of Keycloak を使用できます。すべてのアプリケーションが移行されたら、インポートされたユーザーのリンクを解除し、古いレガシー外部ストアを破棄します。
インポートストラテジーの使用には、いくつかの明確な欠点があります。
- 初めてユーザーを検索するには、Red Hat build of Keycloak データベースを複数回更新する必要があります。これを実行すると、負荷がかかってパフォーマンスが大幅に低下し、Red Hat build of Keycloak データベースに大きな負担がかかる可能性があります。ユーザーフェデレーションされたストレージアプローチは、必要に応じて追加のデータのみを保存し、外部ストアの機能によっては使用されない可能性があります。
- このインポート方法では、ローカルの Red Hat build of Keycloak ストレージと外部ストレージを同期する必要があります。User Storage SPI には同期をサポートするために実装できる機能インターフェイスがありますが、この操作はすぐに面倒で複雑になる可能性があります。
インポートストラテジーを実装するには、ユーザーがローカルにインポートされているかどうかを最初に確認します。ローカルにインポートされている場合には、ローカルユーザーを返します。インポートされていない場合には、ローカルにユーザーを作成して、外部ストアからデータをインポートします。また、ほとんどの変更が自動同期されるように、ローカルユーザーをプロキシー化することも可能です。
これは少し複雑になりますが、PropertyFileUserStorageProvider
を拡張してこのアプローチを取ることができます。最初に createAdapter()
メソッドを修正します。
PropertyFileUserStorageProvider
この方法では、UserStoragePrivateUtil.userLocalStorage(session)
メソッドを呼び出して、ローカルの Red Hat build of Keycloak ユーザーストレージへの参照を取得します。ユーザーがローカルに保存されているかどうかを確認し、ない場合はローカルに追加します。ローカルユーザーの id
を設定しないでください。id
は、Red Hat build of Keycloak が自動生成します。また、UserModel.setFederationLink()
を呼び出して、プロバイダーの ComponentModel
に ID を渡すことにも注意してください。これにより、プロバイダーとインポートされたユーザーの間にリンクが設定されます。
ユーザーストレージプロバイダーが削除されると、そのストレージプロバイダーによってインポートされたユーザーも削除されます。これは、UserModel.setFederationLink()
を呼び出す目的の 1 つです。
また、ローカルユーザーがリンクしている場合は、CredentialInputValidator
インターフェイスおよび CredentialInputUpdater
インターフェイスから実装するメソッドのために、ストレージプロバイダーが依然として委譲される点に留意してください。検証または更新で false
が返されると、Red Hat build of Keycloak はローカルストレージを使用して検証または更新できるか確認します。
また、org.keycloak.models.utils.UserModelDelegate
クラスを使用してローカルユーザーをプロキシー処理している点に注意してください。このクラスは UserModel
の実装です。すべてのメソッドは、それがインスタンス化された UserModel
に委譲するだけです。プロパティーファイルと自動的に同期するため、この委譲クラスの setUsername()
メソッドが上書きされます。プロバイダーの場合、これを使用して、ローカル UserModel
上の他のメソッドを 傍受 して、外部ストアと同期できます。たとえば、get メソッドでは、ローカルストアが同期していることを確認することができます。set メソッドでは、外部ストアがローカルストアと同期し続けます。getId()
メソッドは、ユーザーをローカルで作成したときに自動生成された id を常に返す必要がある点に留意してください。インポート以外の他の例で示されているように、フェデレーション ID は返さないはずです。
プロバイダーが UserRegistrationProvider
インターフェイスを実装している場合、removeUser()
メソッドはローカルストレージからユーザーを削除する必要はありません。ランタイムはこの操作を自動的に実行します。また、ローカルストレージから削除される前に removeUser()
が呼び出されることに注意してください。
6.9.1. ImportedUserValidation インターフェイス リンクのコピーリンクがクリップボードにコピーされました!
この章の最初の部分で、ユーザーへの問い合わせがどのように機能するかを説明しました。最初にローカルストレージを問い合わせし、ユーザーが見つかった場合は、クエリーが終了します。これは、上記の実装で問題になります。ローカル UserModel
をプロキシーして、ユーザー名の同期を維持します。User Storage SPI には、リンクされたローカルユーザーがローカルデータベースから読み込まれるたびに実行されるコールバックがあります。
リンクされたローカルユーザーが読み込まれるたびに、ユーザーストレージプロバイダークラスがこのインターフェイスを実装している場合は、validate()
メソッドが呼び出されます。ここでは、ローカルユーザーをパラメーターとしてプロキシー化して返すことができます。その新しい UserModel
が使用されます。オプションで、ユーザーが外部ストアにまだ存在するかどうかを確認することもできます。validate()
が Null
を返すと、ローカルユーザーがこのデータベースから削除されます。
6.9.2. ImportSynchronization インターフェイス リンクのコピーリンクがクリップボードにコピーされました!
インポートストラテジーにより、ローカルユーザーコピーが外部ストレージと同期できなくなっていることがわかります。おそらくユーザーは外部ストアから削除されてしまっているようです。ユーザーストレージ SPI には、これに対応するために実装できる追加のインターフェイス (org.keycloak.storage.user.ImportSynchronization
) があります。
このインターフェイスはプロバイダーファクトリーによって実装されます。このインターフェイスがプロバイダーファクトリーによって実装されると、プロバイダーの管理コンソール管理ページには追加オプションが表示されます。ボタンをクリックして、手動で強制的に同期させることができます。これにより、ImportSynchronization.sync()
メソッドが呼び出されます。また、同期を自動的にスケジュールできる追加の設定オプションが表示されます。自動同期は syncSince()
メソッドを呼び出します。
6.10. ユーザーキャッシュ リンクのコピーリンクがクリップボードにコピーされました!
ユーザーオブジェクトが ID、ユーザー名、またはメールクエリーによって読み込まれると、キャッシュされます。ユーザーオブジェクトがキャッシュされている場合、これは UserModel
インターフェイス全体を繰り返し処理し、この情報をローカルのインメモリーのみのキャッシュにプルします。クラスターでは、このキャッシュは引き続きローカルに存在しますが、インバリデーションキャッシュになります。ユーザーオブジェクトが変更されると、これはエビクトされます。このエビクションイベントはクラスター全体に伝播され、他のノードのユーザーキャッシュも無効になります。
6.10.1. ユーザーキャッシュの管理 リンクのコピーリンクがクリップボードにコピーされました!
KeycloakSession.getProvider(UserCache.class)
を呼び出してユーザーキャッシュにアクセスできます。
特定のユーザー、特定のレルムに含まれるユーザー、またはキャッシュ全体をエビクトする方法があります。
6.10.2. OnUserCache Callback インターフェイス リンクのコピーリンクがクリップボードにコピーされました!
プロバイダー実装に固有の追加情報をキャッシュすることもできます。ユーザーストレージ SPI には、ユーザーがキャッシュされるたびにのコールバック (org.keycloak.models.cache.OnUserCache
) が設定されます。
public interface OnUserCache { void onCache(RealmModel realm, CachedUserModel user, UserModel delegate); }
public interface OnUserCache {
void onCache(RealmModel realm, CachedUserModel user, UserModel delegate);
}
このコールバックが必要な場合は、プロバイダークラスはこのインターフェイスを実装する必要があります。UserModel
パラメーターは、プロバイダーによって返される UserModel
インスタンスです。CachedUserModel
は、拡張された UserModel
インターフェイスです。これは、ローカルストレージでローカルにキャッシュされるインスタンスです。
CachedUserModel
インターフェイスを使用すると、ユーザーをキャッシュから強制的に削除 (エビクト) し、プロバイダーの UserModel
インスタンスを取得できます。getCachedWith()
メソッドは、ユーザーに関連する追加情報をキャッシュできるマップを返します。たとえば、認証情報は UserModel
インターフェイスの一部ではありません。認証情報をメモリーにキャッシュする必要がある場合は OnUserCache
を実装し、getCachedWith()
メソッドを使用してユーザーの認証情報をキャッシュします。
6.10.3. キャッシュポリシー リンクのコピーリンクがクリップボードにコピーされました!
ユーザーストレージプロバイダーの管理者向けのコンソール管理ページで、固有のキャッシュポリシーを指定できます。
6.11. Jakarta EE の活用 リンクのコピーリンクがクリップボードにコピーされました!
バージョン 20 以降、Keycloak は Quarkus のみに依存します。WildFly とは異なり、Quarkus はアプリケーションサーバーではありません。詳細は、https://www.keycloak.org/migration/migrating-to-quarkus#_quarkus_is_not_an_application_server を参照してください。
したがって、以前のバージョンで Keycloak が WildFly 上で実行されていた場合のように、ユーザーストレージプロバイダーを Jakarta EE コンポーネント内にパッケージ化したり、EJB にしたりすることはできません。
プロバイダー実装は、前のセクションで説明したように、適切なユーザーストレージ SPI インターフェイスを実装するプレーンな Java オブジェクトである必要があります。また、この移行ガイドの説明に従ってパッケージ化してデプロイする必要があります。
次の例に示すように、JPA Entity Manager によって外部データベースを統合できるカスタム UserStorageProvider
クラスを引き続き実装できます。
CDI はサポートされていません。
6.12. REST 管理 API リンクのコピーリンクがクリップボードにコピーされました!
管理者 REST API を使用して、ユーザーストレージプロバイダーのデプロイメントを作成、削除、および更新できます。User Storage SPI は汎用コンポーネントインターフェイス上に構築されるため、その汎用 API を使用してプロバイダーを管理します。
REST Component API は、レルム管理リソース下に存在します。
/admin/realms/{realm-name}/components
/admin/realms/{realm-name}/components
ここでは、この REST API と Java クライアントとのやり取りのみを紹介します。この API から curl
からこの実行方法を抽出できます。
ユーザーストレージプロバイダーを作成するには、プロバイダー ID、文字列 org.keycloak.storage.UserStorageProvider
のプロバイダータイプ、および設定を指定する必要があります。
6.13. 以前のユーザーフェデレーション SPI からの移行 リンクのコピーリンクがクリップボードにコピーされました!
この章では、以前の (すでに廃止された)User Federation SPI を使用してプロバイダーを実装している場合のみを対象としています。
Keycloak バージョン 2.4.0 以前のバージョンでは、User Federation SPI がありました。Red Hat Single Sign-On バージョン 7.0 はサポート対象外ですが、この以前の SPI も使用できます。この以前の User Federation SPI は、Keycloak バージョン 2.5.0 および Red Hat Single Sign-On バージョン 7.1 から削除されました。ただし、この章では、この SPI でプロバイダーを作成している場合の移植に使用できるストラテジーを説明します。
6.13.1. インポートと非インポート リンクのコピーリンクがクリップボードにコピーされました!
以前の User Federation SPI は、Red Hat build of Keycloak のデータベースでユーザーのローカルコピーを作成し、情報を外部ストアからローカルコピーにインポートする必要がありました。ただし、要件ではなくなりました。以前のプロバイダーもそのままの状態で移植できますが、インポートなしのストラテジーの方が適しているかどうかを検討する必要があります。
インポートストラテジーの利点:
- 基本的に、Red Hat build of Keycloak は外部ストアの永続ユーザーキャッシュになります。ユーザーがインポートされると、外部ストアに到達できなくなるため、負荷がなくなります。
- 公式ユーザーストアとして Red Hat build of Keycloak に移行し、以前の外部ストアを非推奨にする場合は、アプリケーションを徐々に移行して Red Hat build of Keycloak を使用できます。すべてのアプリケーションが移行されたら、インポートされたユーザーのリンクを解除し、古いレガシー外部ストアを破棄します。
インポートストラテジーの使用には、いくつかの明確な欠点があります。
- 初めてユーザーを検索するには、Red Hat build of Keycloak データベースを複数回更新する必要があります。これを実行すると、負荷がかかってパフォーマンスが大幅に低下し、Red Hat build of Keycloak データベースに大きな負担がかかる可能性があります。ユーザーフェデレーションされたストレージアプローチは、必要に応じて追加のデータのみを保存し、外部ストアの機能によっては使用されない可能性があります。
- このインポート方法では、ローカルの Red Hat build of Keycloak ストレージと外部ストレージを同期する必要があります。User Storage SPI には同期をサポートするために実装できる機能インターフェイスがありますが、この操作はすぐに面倒で複雑になる可能性があります。
6.13.2. UserFederationProvider と UserStorageProvider リンクのコピーリンクがクリップボードにコピーされました!
最初に、UserFederationProvider
が完全なインターフェイスであったことに留意してください。このインターフェイスにすべてのメソッドを実装しました。ただし、UserStorageProvider
は、このインターフェイスを、必要に応じて実装する複数の機能インターフェイスに分割します。
UserFederationProvider.getUserByUsername()
および getUserByEmail()
には、新しい SPI に完全に同等のものが含まれます。この 2 つの違いは、インポートの方法です。インポートストラテジーを続行する場合は、KeycloakSession.userStorage().addUser()
を呼び出してユーザーをローカルに作成しなくなりました。代わりに KeycloakSession.userLocalStorage().addUser()
を呼び出します。userStorage()
メソッドがなくなりました。
UserFederationProvider.validateAndProxy()
メソッドは任意の機能インターフェイス ImportedUserValidation
に移動しました。以前のプロバイダーをそのまま移植する場合は、このインターフェイスを実装する必要があります。また、以前の SPI では、ローカルユーザーがキャッシュにある場合でも、ユーザーがアクセスされたたびにこのメソッドが呼び出されていました。このメソッドは、後の SPI では、ローカルユーザーがローカルストレージからロードされる場合にのみ呼び出されます。ローカルユーザーがキャッシュされていると、ImportedUserValidation.validate()
メソッドは呼び出されません。
UserFederationProvider.isValid()
メソッドは、後続の SPI に存在しなくなりました。
UserFederationProvider
のメソッド synchronizeRegistrations()
、registerUser()
、および removeUser()
が UserRegistrationProvider
機能インターフェイスに移動しました。プロバイダーがユーザーの作成や削除をサポートしていない場合は、この新しいインターフェイスを実装する必要はありません。以前のプロバイダーが新規ユーザー登録のサポートを切り替える場合は、これが新しい SPI でサポートされ、プロバイダーがユーザーの追加をサポートしていない場合は UserRegistrationProvider.addUser()
から Null
を返します。
認証情報を中心とする以前の UserFederationProvider
メソッドは、CredentialInputValidator
インターフェイスおよび CredentialInputUpdater
インターフェイスにカプセル化されるようになりました。また、認証情報の検証または更新をサポートしているかどうかに応じて実装することもできます。認証情報管理は、以前は UserModel
メソッドに存在していました。これらは CredentialInputValidator
インターフェイスおよび CredentialInputUpdater
インターフェイスに移動されています。CredentialInputUpdater
インターフェイスを実装していない場合は、Red Hat build of Keycloak ストレージでプロバイダーが提供する認証情報をローカルで上書きできます。そのため、認証情報を読み取り専用にするには、CredentialInputUpdater.updateCredential()
メソッドを実装し、ReadOnlyException
を返します。
searchByAttributes()
、getGroupMembers()
などの UserFederationProvider
クエリーメソッドは、任意のインターフェイス UserQueryProvider
でカプセル化されるようになりました。このインターフェイスを実装しないと、ユーザーは管理コンソールでは表示されません。ただし、引き続きログインはできます。
6.13.3. UserFederationProviderFactory と UserStorageProviderFactory リンクのコピーリンクがクリップボードにコピーされました!
以前の SPI の同期メソッドは、任意の ImportSynchronization
インターフェイス内でカプセル化されるようになりました。同期ロジックを実装している場合、新しい UserStorageProviderFactory
が ImportSynchronization
インターフェイスを実装します。
6.13.4. 新規モデルへのアップグレード リンクのコピーリンクがクリップボードにコピーされました!
User Storage SPI インスタンスは異なるリレーショナルテーブルのセットに保存されます。Red Hat build of Keycloak は、移行スクリプトを自動的に実行します。以前のユーザーフェデレーションプロバイダーがレルムにデプロイされると、データの id
を含む、後のストレージモデルにそのまま変換されます。この移行は、以前のユーザーフェデレーションプロバイダーのプロバイダー ID ("ldap", "kerberos") と同じユーザーストレージプロバイダーが存在する場合のみ行われます。
そのため、この知識をもとに、さまざまなアプローチを取ることができます。
- 以前の Red Hat build of Keycloak デプロイメントでは、以前のプロバイダーを削除できます。これにより、インポートした全ユーザーのローカルリンクコピーが削除されます。その後、Red Hat build of Keycloak をアップグレードする際に、新しいプロバイダーをレルムにデプロイして設定します。
-
2 つ目のオプションは、
UserStorageProviderFactory.getId()
という同じプロバイダー ID を持つように新規プロバイダーを作成します。このプロバイダーがサーバーにデプロイされていることを確認します。サーバーを起動し、組み込み移行スクリプトが以前のデータモデルから後のデータモデルに変換されるようにします。この場合、以前にリンクしたインポート済みのユーザーはすべて機能し、同じ状態になります。
インポートストラテジーを廃止して、ユーザーストレージプロバイダーを書き換えた場合は、Red Hat build of Keycloak をアップグレードする前に以前のプロバイダーを削除することを推奨します。これにより、インポートしたユーザーにリンクされたローカルのインポートコピーが削除されます。
6.14. ストリームベースのインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak のユーザーストレージインターフェイスの多くは、潜在的に大きなオブジェクトのセットを返すことができるクエリーメソッドを含んでおり、メモリー消費や処理時間の面で大きな影響を与える可能性があります。これは、クエリーメソッドのロジックでオブジェクトの内部状態の小さなサブセットのみが使用される場合に特に当てはまります。
これらのクエリーメソッドで大規模なデータセットを処理するためのより効率的な代替手段を開発者に提供するために、ユーザーストレージインターフェイスに Streams
サブインターフェイスが追加されました。これらの Streams
サブインターフェイスは、スーパーインターフェイスのオリジナルのコレクションベースのメソッドをストリームベースのバリアントに置き換え、コレクションベースのメソッドをデフォルトにしています。コレクションベースのクエリーメソッドのデフォルトの実装では、Stream
対応のメソッドが呼び出され、結果が適切なコレクションタイプに収集されます。
Streams
サブインターフェイスは、データセットを処理するためのストリームベースのアプローチに焦点を当てた実装を可能にし、そのアプローチによる潜在的なメモリーとパフォーマンスの最適化の恩恵を受けることができます。実装される Streams
サブインターフェイスを提供するインターフェイスには、いくつかの 機能インターフェイス、org.keycloak.storage.federated
パッケージ内のすべてのインターフェイス、およびカスタムストレージ実装の範囲に応じて実装される可能性があるいくつかのインターフェイスが含まれます。
開発者向けに Streams
サブインターフェイスを提供しているインターフェイスのリストを参照してください。
パッケージ | クラス |
|
|
|
|
| すべてのインターフェイス |
|
|
(*) はインターフェイスが 機能インターフェイス であることを示しています。
ストリームアプローチの恩恵を受けたいユーザーストレージのカスタム実装は、オリジナルのインターフェイスの代わりに Streams
サブインターフェイスを実装する必要があります。たとえば、次のコードでは、UserQueryProvider
インターフェイスの Streams
バリアントを使用しています。
第7章 Vault SPI リンクのコピーリンクがクリップボードにコピーされました!
7.1. Vault プロバイダー リンクのコピーリンクがクリップボードにコピーされました!
org.keycloak.vault
パッケージの Vault SPI を使用して、Red Hat build of Keycloak のカスタム拡張を作成し、任意の Vault 実装に接続できます。
組み込みの files-plaintext
プロバイダーは、この SPI の実装例です。一般的に以下のルールが適用されます。
-
レルム間でシークレットのリークを防ぐために、レルムで取得できるシークレットを分離したり、制限したりすることができます。この場合、プロバイダーはシークレットの検索時に、エントリーの前にレルム名を付けるなど、レルム名を考慮する必要があります。たとえば、式
${vault.key}
は、レルム A またはレルム B で使用されるかに応じて、一般的に異なるエントリー名に評価されます。レルムを区別するには、レルムを、KeycloakSession
パラメーターから利用できるVaultProviderFactory.create()
メソッドから、作成されたVaultProvider
インスタンスに渡す必要があります。 -
Vault プロバイダーは、指定したシークレット名に
VaultRawSecret
返す単一のメソッドobtainSecret
を実装します。そのクラスは、シークレットの表現をbyte[]
またはByteBuffer
のいずれかに保持し、必要に応じて 2 つの間で変換することが期待されます。このバッファーは、以下で説明されているように使用後に破棄されることに注意してください。
カスタムプロバイダーをパッケージ化してデプロイする方法は、サービスプロバイダーインターフェイス の章を参照してください。
7.2. Vault からの値の使用 リンクのコピーリンクがクリップボードにコピーされました!
vault には機密データが含まれ、Red Hat build of Keycloak がシークレットを適宜処理します。シークレットにアクセスする場合には、シークレットは vault から取得され、必要な期間のみ JVM メモリーに保持されます。その後、JVM メモリーからコンテンツの破棄を試みることができます。これは、以下のように try
-with-resources ステートメント内でのみ Vault シークレットを使用して実行されます。
この例では、シークレットにアクセスするためのエントリーポイントとして KeycloakSession.vault()
を使用します。VaultProvider.obtainSecret
メソッドを直接使用することも可能になります。ただし、vault()
メソッドは、オリジナルの解釈されていない値 (vault().getRawSecret()
メソッド経由) を取得するのに加え、(通常はバイト配列である) 未編集のシークレットを文字アレイ (vault().getCharSecret()
経由) または String
(via vault().getStringSecret()
経由) として解釈できるという利点があります。
String
オブジェクトは変更できないため、ランダムなガベージでコンテンツを破棄できないことに注意してください。デフォルトの VaultStringSecret
の実装では、String
の内面化を防ぐための対策が取られていますが、String
オブジェクトに格納されているシークレットは、少なくとも次の GC ラウンドまで存続します。そのため、プレーンなバイト配列、文字配列、およびバッファーを使用することが推奨されます。