私は、JWT 署名に使われる公開鍵を変更した場合、リソースサーバで新しい公開鍵を取得する作業が必要だと考えていました。
しかし、結論から言うとこれは間違いでした。Spring Boot + Spring Security を使用している場合は何もせずに自動対応されます。
本当にそうなのか、少し不安に思い検証してみました。
Keycloak で公開鍵の追加
Keycloak に公開鍵を追加して試してみます。
Realm settings > Keys
ここで鍵の一覧を確認できます。JWT の署名で必要なのはRS256 になります。既存の鍵が1つ存在します。

※画像は Keycloak バージョン 26.1.4 のものです。以下同様です。
公開鍵を追加する場合、Add providers > Add provider をクリックします。

鍵の種類を選ぶ画面が出ますので、rsa-generated を選択します。

既存の鍵と区別するためにName をrsa-generated-test とします。

一覧画面で追加されていることが確認できます。

この状態で、JWKS エンドポイントをブラウザで表示してみます。
https://<KEYCLOAK_HOST>/realms/<REALM_NAME>/protocol/openid-connect/certs
表示されたJSON をchrome console で解析させると、kid が8wY… から始まる鍵が公開されていることが分かります。

古い鍵のprovider のEnabled をoff に変更すると、JWKS エンドポイントからも削除されます。

Spring Boot で検証
以下の順序で検証してみました。
- Spring boot を起動
- Keycloak に新しい公開鍵の追加して、古い鍵を無効化する
- 新しい鍵で著名されたJWT をSpring boot に送信
結果、Spring boot を再起動することなく、新しい鍵によるJWT 検証が行われました。
内部の挙動(推測)
Spring boot はJWK を一定時間キャッシュします。
JWT ヘッダーに含まれるkid に対応する公開鍵がキャッシュに存在しない場合、JWKS エンドポイントを呼び出して新たな鍵を取得した上で再度検証を行なっていると考えられます。
便利ですね。
コメントを残す