Contents
Keycloak OIDC カスタムクレーム 実装 方法:Quarkus拡張機能を使わない独自実装手順
Keycloak経由でOIDC認証時にカスタムクレームを実装する方法を、Quarkus拡張機能を使わずにJavaで独自に構築する具体的な手順を解説します。企業のシングルサインオン(SSO)環境や自社開発の認可フローでカスタムクレームが必要な場合、この記事が実装の参考になります。
Keycloakでのカスタムクレーム定義の手順
Keycloakサーバーでカスタムクレームを定義するには、Realm設定における属性追加とクレームマッピングの構成が必要です。管理者インターフェース経由で行うことで、User FederationやIDプロバイダーとの連携が可能です。
なぜカスタムクレームが必要か?
カスタムクレームは、ロールベース認証やセキュリティ制御の柔軟な実装に不可欠です。たとえば、特定のユーザーに「admin」ロールを割り当てることで、アクセス制限を動的に適用できます。
Realm設定における属性追加手順
Keycloak管理画面でカスタム属性を定義するには、以下の手順を行います。
- Realm選択とUsers属性画面へのアクセス
- Keycloak管理者インターフェースを開き、対象のRealmを選択します。
-
メニューから「Users > Attributes」に移動します。
-
カスタム属性の作成とユーザーへの適用
- 「Add Attribute」ボタンをクリックし、名前(例:
custom_role)と値(例:admin)を入力します。 - 作成した属性を特定のユーザーに割り当てることで、OIDCフローでのクレーム送信が可能になります。
クレームマッピング設定の一覧
以下はKeycloakにおけるカスタムクレームの有効化手順とその目的です。
| ステップ | 内容 | 補足 |
|---|---|---|
| 1 | 「Realm Settings > OpenID Provider > User Info」を開く | ID TokenおよびUserInfoエンドポイントでの出力設定 |
| 2 | 「User Attributes to Include in the Claims」にカスタム属性を追加 | カスタムクレームの明示的なマッピング |
| 3 | 「Include User Attributes as Claims in ID Token and UserInfo Response」にチェック | ユーザー情報取得時の自動出力有効化 |
注意: KeycloakのID TokenおよびUserInfo経由でのクレーム取得は、アプリケーション側で処理を実装する必要があります。
OIDCフローにおけるカスタムクレーム取得方法
OIDCフローでは、ID Tokenの構造解析やUserInfoエンドポイントからのクレーム取得ロジックが必要になります。Javaアプリケーションでこれらを実装するには、JWTライブラリ(例: Nimbus JOSE)を使用します。
ID Tokenの構造解析手順
ID Tokenのデコードとカスタムクレーム取得は、以下のように処理されます。
- ID Tokenの取得とペイロード分解
-
OAuth2認証後のレスポンスで
id_tokenを取得し、JSON形式に変換します。 -
カスタムクレームの抽出
getClaim()メソッドを使用して、custom_roleなどの特定クレームを取得します。
|
1 2 3 4 5 6 7 8 9 10 11 |
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; String idToken = "取得したトークン"; JwtParser parser = Jwts.parserBuilder() .setSigningKey(keycloakの公開鍵) // Keycloakから取得 .build(); Jws<Claims> jws = parser.parseClaimsJws(idToken); String customRole = jws.getBody().get("custom_role", String.class); // カスタムロール抽出 |
UserInfoエンドポイントからのクレーム取得手順
UserInfoエンドポイントを介してカスタムクレームを取得するには、以下のような処理が求められます。
- アクセストークンでのアクセス
-
/protocol/openid-connect/userinfoエンドポイントにリクエストします。 -
レスポンスの解析とカスタムクレームの抽出
- クライアントアプリケーションで、取得したマップ型データから
custom_roleを参照します。
|
1 2 3 4 5 6 7 8 9 |
HttpEntity<String> entity = new HttpEntity<>(headers); // アクセストークンをヘッダーに含める ResponseEntity<Map<String, Object>> response = restTemplate.postForEntity( "https://keycloak.realm/userinfo", entity, Map.class ); String customRoleFromUserInfo = (String) response.getBody().get("custom_role"); // UserInfo経由での抽出 |
JWT検証時の拡張処理実装
Keycloakから送信されるJWTトークンの署名検証後に、カスタムロジックを挿入して処理を拡張します。この段階でクレーム値を変更または追加できますが、セキュリティ上慎重に設計が必要です。
署名検証後のカスタムロジックの例
Javaアプリケーションでは、JwtClaimsSetオブジェクトを利用して拡張可能です:
- 有効期限の動的調整
- カスタムクレームを追加する際、セキュリティポリシーに合った有効期間設定を行います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.time.Instant; import java.util.Map; Map<String, Object> claims = new HashMap<>(); claims.put("custom_expiry", Instant.now().plusSeconds(3600).getEpochSecond()); JwtClaimsSet extendedClaims = JwtClaimsSet.builder() .issuedAt(Instant.now()) .expiresAt(Instant.now().plusSeconds(3600)) .subject(sub) .claim("custom_role", "admin") .claims(claims) .build(); String newToken = Jwts.builder() .setClaims(extendedClaims) .signWith(key, SignatureAlgorithm.RS256) .compact(); |
注意: カスタムクレームの追加は、Keycloak設定と一致させることが必須です。
Quarkus環境でのアクセス制御拡張
QuarkusではSecurityConstraintやRolesAllowedアノテーションの代替として、認可チェック時のクレーム参照ロジックを独自実装できます。この方法で、カスタムクレーム値に基づいた動的なアクセス制限が可能です。
セキュリティ制約のカスタム定義例
QuarkusはSecurityIdentityインターフェースを通じて認証情報を提供します:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public class CustomAccessControl implements SecurityConstraint { @Override public boolean isPermitted(SecurityContext context, String role) { // セキュリティコンテキストからカスタムクレームを取得 Map<String, Object> claims = context.getSecurityContext().getAttributes(); String customRole = (String) claims.get("custom_role"); return "admin".equals(customRole); // 管理者ロールのみ許可 } } |
認可チェック時のクレーム参照フロー
カスタムアクセス制御を適用するには、@RolesAllowedアノテーションの代替として@CustomSecurityConstraintのような独自アノテーションを作成し、メソッドに適用します:
|
1 2 3 4 5 |
@CustomSecurityConstraint("admin") public Response getAdminData() { return Response.ok("管理者専用データ").build(); } |
デモ環境構築と検証手順
ローカル開発環境で実装したカスタムクレームが正しく動作するかを確認します。Keycloakとの連携テストからQuarkusアプリケーションの認証フローまでの一連のプロセスを検証しましょう。
ローカル開発環境での整合性テスト
以下は、KeycloakとQuarkusアプリケーションの統合検証手順です:
- Keycloakサーバーのローカル起動
- DockerやDocker ComposeでKeycloakを起動し、カスタムクレームが定義されていることを確認します。
- Quarkusアプリケーションでのトークン挿入と検証
id_tokenおよびUserInfoエンドポイントから取得したクレームの処理が正しく動作するかテストします。
リアルタイムなクレーム反映確認
Keycloak管理者インターフェースでカスタム属性を変更し、アプリケーションでの反映テストを行います:
- Keycloak側での変更(例:
custom_roleをuserへ) - 管理者インターフェースからユーザーの属性情報を更新します。
- クライアントアプリケーションでの再認証処理
- トークンの再発行を行い、変更後の
custom_roleが即時反映されているかを確認します。
参考: デモ用コードはGitHubリポジトリに公開しています。(リンクは2023年11月時点の最新版を指す)
まとめ
Keycloakにおけるカスタムクレームの実装は、セキュリティ制御やロールベース認証のような具体的なユースケースを想定した設計が不可欠です。Quarkus環境においても、独自のアクセス制御ロジックを組み込むことで、柔軟かつ信頼性のある認可フローを実現できます。
また、KeycloakやNimbus JOSEライブラリの仕様変更に注意しつつ、Quarkus公式ドキュメントとの互換性を保った開発が推奨されます。