【Keycloak】アクセストークンの Audience を変更する
はじめに
Keycloak のアクセストークンにある aud
クレームがデフォルトで account
になっています。この aud
が何者か気になったので、調べてみました。
その結果、アクセストークンの aud
を変更する方法がわかりましたので、まとめます。
成果物
https://github.com/kntks/blog-code/tree/main/2024/09/keycloak-token-audience
環境構築
バージョン
バージョン | |
---|---|
Mac | Sonoma 14.5 |
Keycloak | 25.0.6 |
Docker | 26.0.0 |
Docker Compose | v2.24.5 |
Terraform | 1.9.5 |
Keycloak のセットアップ
compose.yaml
ファイルを作成し、Keycloak を定義します。
docker compose コマンドを実行して Keycloak を起動します。
Terraformを実行する
Terraform を使用するために Keycloak に terraform クライアント を作成します。
Keycloak で terraform クライアントを作成したら、クライアントシークレットをコピーし、以下ように、client_id, client_secret, url を設定します。
terraform apply で Keycloak の設定を行います。
Audience とは
アクセストークンの Audience
Audience(オーディエンス)は、JWT(JSON Web Token)のクレームの1つで、JWT が意図されている受取人を識別します。
The “aud” (audience) claim identifies the recipients that the JWT is intended for.
「aud」(オーディエンス)クレームは、JWTが意図されている受取人を識別します。
ID トークンの Audience
ID トークンの aud
は、OAuth 2.0 クライアント ID である必要があります。
REQUIRED. Audience(s) that this ID Token is intended for. It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value.
(訳)必須。このIDトークンが意図されているオーディエンス。オーディエンスの値として、必ずRelying Party(依存するサービス)のOAuth 2.0 client_idを含める必要があります。
引用:ID Token - OpenID Connect Core 1.0 incorporating errata set 2
Audience の確認方法
Audience の設定方法に進む前に、トークンの発行とデコード方法を紹介します。
方法は2つあります。
- Direct access grants を使用してトークンを取得する
- Evaluate を使用する
Direct access grants を使用してトークンを取得する
myapp クライアントの Settings
タブを開き、Direct access grants
を確認します。
チェックが入っていない場合は、チェックを入れて保存します。
Credentials
タブからクライアントシークレットをコピーしてください。
先ほどコピーしたクライアントシークレットを以下の curl コマンドに設定し、実行すると、アクセストークンと ID トークンを取得できます。
今回は以下のスクリプトを実行することで、アクセストークンと ID トークンをデコードします。
このスクリプトを実行すると、以下のような結果が得られます。
アクセストークン
aud
が account
になっていることがわかります。さらに、realm_access
や resource_access
にデフォルトロールが含まれていることも確認できます。
ID トークン
aud
はクライアント ID である myapp
になっていることがわかります。
Evaluate を使用する
Client scopes
タブを開き、Evaluate
をクリックすると、クライアントスコープを評価でき、実施にどのようなクレームが含まれるかを確認できます。
Keycloak のクライアント設定
Full scope allowed を OFF にする
先ほど access_token
のデコード結果から使わないデフォルトのロールがありました。
Keycloak はデフォルトで Full scope allowed
が ON になっているため、クライアントに設定されたデフォルトロールがアクセストークンに含まれます。
そのため、Full scope allowed
を OFF にすることで、デフォルトのロールを取り除きます。
myapp
のクライアントページに移動し、Client scopes
タブを開くと、myapp-dedicated
があるのでクリックします。
Scope
タブに切り替えて Full scope allowed
を OFF にして保存します。
再度、decode.sh を実行すると access_token
から aud
や realm_access
、resource_access
が無くなったことを確認できます。
Audiance の設定方法
ここではアクセストークンの aud
を変更する方法を説明します。
audience
に値をセットする方法は2つあります。
参考:Audience support - Keycloak Documentation
クライアントロールを使用した自動追加
Client scopes
ページに roles
という名前のクライアントロールがデフォルトで存在します。
roles
をクリックし、 Mappers
タブを開くと、audience resolve
が設定されています。
このマッパーは、自分自身(クライアント)とは別クライアントのロールを持っている場合、別クライアント ID を自動的に aud
に追加します。
An Audience Resolve protocol mapper is defined in the default client scope roles.
Audience Resolveプロトコルマッパーは、デフォルトのクライアントスコープ「roles」に定義されています。The mapper checks for clients that have at least one client role available for the current token.
このマッパーは、現在のトークンに対して少なくとも1つのクライアントロールが利用可能なクライアントをチェックします。The client ID of each client is then added as an audience, which is useful if your service clients rely on client roles.
そして、各クライアントのクライアントIDがオーディエンスとして追加されます。これは、サービスクライアントがクライアントロールに依存している場合に役立ちます。
aud にクライアント ID が自動で追加されることを確認する
実際に、myapp クライアントに realm-management
クライアントのロールを追加して、aud
に realm-management
クライアント ID が追加されることを確認します。
今回は、realm-management
クライアントにあるロール view-client
を myapp クライアントに追加します。
myapp
クライアントの Client scopes
タブを開き、myapp-dedicated
クライアントスコープをクリックします。
※ 新規にクライアントスコープを作成しても構いません。
Scope
タブに切り替えて、view-client
を追加して保存します。
アクセストークンにロールを反映するためには、ユーザーにもロールを割り当てる必要があります。
これで、myapp クライアントと myuser に view-client
ロールが割り当てられました。アクセストークンを確認してみましょう。
意図した通り、view-client
は realm-management
クライアントのロールなので、aud
に realm-management
クライアント ID が自動で追加されることを確認できました。
先ほど、クライアントとユーザーに紐付けた view-client
ロールは外します。
ハードコード
クライアントロールを使用した aud
の自動追加では、自分自身のクライアント ID をアクセストークンの aud
に追加することはできません。
そのためもし、自分自身のクライアント ID をアクセストークンの aud
に追加したい場合は、ハードコードする必要があります。
そのほかにも、URLなどのカスタム値を設定するときに使用できます。
aud にクライアント ID が追加されることを確認する
今度は、アクセストークンの aud
を自分自身のクライアント ID(myapp)に変更します。
再度、myapp
クライアントの Client scopes
タブを開き、myapp-dedicated
クライアントスコープをクリックします。
Mappers
タブから Configure a new mapper
をクリックしてください。
Audience
を選択します。
Include Client Audience
にクライアント ID である myapp
を入力して保存します。
設定が完了しました。アクセストークンを確認してみましょう。
アクセストークンをデコードした結果、aud
に myapp
クライアント ID が追加されることを確認できました。
まとめ
- Audience は JWT のクレームの1つです、
- アクセストークンの
aud
は JWT が意図されている受取人です。 - ID トークンの
aud
は OAuth 2.0 クライアント ID である必要があります。 - Keycloak でアクセストークンの
aud
を変更する方法は2つあります。- クライアントロールを使用した自動追加
- ハードコード