OpenID Connect(OIDC)ベアラートークン認証によるサービスアプリケーションの保護
Quarkus OpenID Connect (OIDC) エクステンションを使用して、Bearer トークン認証で Jakarta REST アプリケーションを保護します。 ベアラートークンは、OIDC および OAuth 2.0 準拠の認可サーバー (Keycloak など) によって発行されます。
OIDC ベアラートークン認証の詳細は、Quarkus の OpenID Connect (OIDC) ベアラートークン認証 ガイドを参照してください。
OIDC 認可コードフロー認証を使用して Web アプリケーションを保護する場合は、Web アプリケーションを保護するための OpenID Connect 認可コードフローメカニズム ガイドを参照してください。
要件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOMEが適切に設定されていること -
Apache Maven 3.9.11
-
動作するコンテナランタイム(Docker, Podman)
-
使用したい場合は、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
アーキテクチャー
この例では、2 つのエンドポイントを提供するシンプルなマイクロサービスをビルドする方法を示します。
-
/api/users/me -
/api/admin
これらのエンドポイントは保護されており、クライアントがリクエストとともにベアラートークンを送信した場合にのみアクセスできます。ベアラートークンは有効 (署名、有効期限、audience など) であり、マイクロサービスによって信頼されている必要があります。
Keycloak サーバーはベアラートークンを発行し、トークンが発行されたサブジェクトを表します。 これは OAuth 2.0 認可サーバーであるため、トークンはユーザーに代わって動作するクライアントも参照します。
有効なトークンを持つすべてのユーザーは、/api/users/me エンドポイントにアクセスできます。 レスポンスとして、トークンの情報から取得したユーザーの詳細を含む JSON ドキュメントを返します。
/api/admin エンドポイントは RBAC (ロールベースのアクセス制御) で保護されており、admin ロールを持つユーザーのみがアクセスできます。 このエンドポイントでは、@RolesAllowed アノテーションを使用して、アクセス制約を宣言的に適用します。
ソリューション
次のセクションの指示に従って、アプリケーションを段階的に作成します。 完成した例に直接進むこともできます。
git clone https://github.com/quarkusio/quarkus-quickstarts.git コマンドを実行して Git リポジトリーをクローンできます。または、https://github.com/quarkusio/quarkus-quickstarts/archive/main.zip[アーカイブ] をダウンロードできます。
ソリューションは、security-openid-connect-quickstart ディレクトリー にあります。
Maven プロジェクトの作成
oidc エクステンションを使用して新しい Maven プロジェクトを作成することも、既存の Maven プロジェクトにエクステンションを追加することもできます。 次のいずれかのコマンドを実行します。
新しい Maven プロジェクトを作成するには、次のコマンドを使用します。
Windowsユーザーの場合:
-
cmdを使用する場合、(バックスラッシュ
\を使用せず、すべてを同じ行に書かないでください)。 -
Powershellを使用する場合は、
-Dパラメータを二重引用符で囲んでください。例:"-DprojectArtifactId=security-openid-connect-quickstart"
If you already have your Quarkus project configured, you can add the oidc extension to your project by running the following command in your project base directory:
quarkus extension add oidc ./mvnw quarkus:add-extension -Dextensions='oidc' ./gradlew addExtension --extensions='oidc' これにより、ビルドファイルに次の内容が追加されます。
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency> implementation("io.quarkus:quarkus-oidc") アプリケーションの記述
-
次の例に示すように、通常の Jakarta REST リソースである
/api/users/meエンドポイントを実装します。package org.acme.security.openid.connect; import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import org.jboss.resteasy.reactive.NoCache; import io.quarkus.security.identity.SecurityIdentity; @Path("/api/users") public class UsersResource { @Inject SecurityIdentity securityIdentity; @GET @Path("/me") @RolesAllowed("user") @NoCache public User me() { return new User(securityIdentity); } public static class User { private final String userName; User(SecurityIdentity securityIdentity) { this.userName = securityIdentity.getPrincipal().getName(); } public String getUserName() { return userName; } } } -
次の例に示すように、
/api/adminエンドポイントを実装します。package org.acme.security.openid.connect; import jakarta.annotation.security.RolesAllowed; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; @Path("/api/admin") public class AdminResource { @GET @RolesAllowed("admin") @Produces(MediaType.TEXT_PLAIN) public String admin() { return "granted"; } }この例の主な違いは、
adminロールを付与されたユーザーのみがエンドポイントにアクセスできることを確認する際に、@RolesAllowedアノテーションが使用される点です。
SecurityIdentity のインジェクションは、 @RequestScoped と @ApplicationScoped の両方のコンテキストでサポートされています。
アプリケーションの設定
-
src/main/resources/application.propertiesファイルで次の設定プロパティーを設定して、Quarkus OpenID Connect (OIDC) エクステンションを設定します。%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.oidc.client-id=backend-service quarkus.oidc.credentials.secret=secret # Tell Dev Services for Keycloak to import the realm file # This property is not effective when running the application in JVM or native modes quarkus.keycloak.devservices.realm-path=quarkus-realm.json
以下の場合:
-
%prod.quarkus.oidc.auth-server-urlは、OpenID Connect (OIDC) サーバーのベース URL を設定します。%prod.プロファイル接頭辞により、アプリケーションを開発 (dev) モードで実行する際に、Dev Services for Keycloakがコンテナーを起動するようになります。 詳細は、アプリケーションを開発モードで実行する セクションを参照してください。 -
quarkus.oidc.client-idは、アプリケーションを識別するクライアント ID を設定します。 -
quarkus.oidc.credentials.secretは、client_secret_basic認証方法で使用されるクライアントシークレットを設定します。
詳細は、Quarkus の OpenID Connect (OIDC) 設定プロパティー ガイドを参照してください。
アプリケーションを開発モードで実行する
Put the realm configuration file in the src/main/resources application folder so that it gets copied to the classpath and imported automatically to Keycloak. You do not need to do this if you have already built a complete solution, in which case, this realm file is added to the classpath during the build.
-
開発モードでアプリケーションを実行するには、次のコマンドを実行します。
CLIquarkus devMaven./mvnw quarkus:devGradle./gradlew --console=plain quarkusDev-
Dev Services for Keycloak は、Keycloak コンテナーを起動し、
quarkus-realm.jsonをインポートします。
-
-
/q/dev-ui にある Dev UI を開きます。 次に、
OpenID Connectカードで、Keycloak providerリンクをクリックします。 -
OpenID Connect Dev UIによって提供されるSingle Page Applicationにログインするように求められたら、次の手順を実行します。-
userロールを持つalice(パスワード:alice) としてログインします。-
/api/adminにアクセスすると、ステータスコード403が返されます。 -
/api/users/meにアクセスすると、ステータスコード200が返されます。
-
-
ログアウトし、
adminとuserの両方のロールを持つadmin(パスワード:admin) として再度ログインします。-
/api/adminにアクセスすると、ステータスコード200が返されます。 -
/api/users/meにアクセスすると、ステータスコード200が返されます。
-
-
Keycloakサーバーの起動と設定
| Do not start the Keycloak server when you run the application in dev mode; |
+ . To start a Keycloak server, you can use Docker to run the following command:
+
docker run --name keycloak -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev -
Where the
keycloak.versionis set to version26.4.5or later.-
Keycloak サーバーには localhost:8180 からアクセスできます。
-
Keycloak 管理コンソールにアクセスするには、次のログイン認証情報を使用して
adminユーザーとしてログインします。
-
-
ユーザー名:
admin -
パスワード:
admin-
新しいレルムを作成するには、アップストリームコミュニティーリポジトリーから レルム設定ファイル をインポートします。
-
詳細は、Keycloak ドキュメントの 新しいレルムの作成と設定 を参照してください。
| Keycloak Admin Client を使用してアプリケーションから Keycloak サーバーを設定するには、セットアップに基づいて次のいずれかのエクステンションを含めます。
これらのガイドラインは、REST サーバー、REST クライアント、またはその両方で作業しているかどうかに関係なく、Keycloak Admin Client と REST フレームワークをシームレスに統合できるようにします。 詳細は、Quarkus Keycloak Admin Client ガイドを参照してください。 |
JVM モードでアプリケーションを実行する
-
アプリケーションをコンパイルします。
CLIquarkus buildMaven./mvnw installGradle./gradlew build -
アプリケーションを実行します。
java -jar target/quarkus-app/quarkus-run.jar
ネイティブモードでアプリケーションを実行する
この同じデモを、変更を加えずにそのままネイティブモードにコンパイルできます。 これは、実稼働環境に JVM をインストールする必要がなくなることを意味します。 ランタイムテクノロジーは生成されたバイナリーに組み込まれ、必要最小限のリソースで実行できるように最適化されています。
コンパイルには少し時間がかかるため、この手順はデフォルトで無効になっています。
-
nativeプロファイルを有効にして、アプリケーションを再度ビルドします。CLIquarkus build --nativeMaven./mvnw install -DnativeGradle./gradlew build -Dquarkus.native.enabled=true -
しばらく待ってから、次のバイナリーを直接実行します。
./target/security-openid-connect-quickstart-1.0.0-SNAPSHOT-runner
アプリケーションのテスト
開発モードでのアプリケーションのテストの詳細は、前述のアプリケーションを開発モードで実行する セクションを参照してください。
curl を使用して、JVM またはネイティブモードで起動したアプリケーションをテストできます。
-
アプリケーションはベアラートークン認証を使用するため、アプリケーションリソースにアクセスするには、まず Keycloak サーバーからアクセストークンを取得する必要があります。
export access_token=$(\ curl --insecure -X POST http://localhost:8180/realms/quarkus/protocol/openid-connect/token \ --user backend-service:secret \ -H 'content-type: application/x-www-form-urlencoded' \ -d 'username=alice&password=alice&grant_type=password' | jq --raw-output '.access_token' \ ) |
|
上記の例では、ユーザー alice のアクセストークンを取得します。
-
どのユーザーも
http://localhost:8080/api/users/meエンドポイントにアクセスでき、ユーザーの詳細を含む JSON ペイロードが返されます。
curl -v -X GET \ http://localhost:8080/api/users/me \ -H "Authorization: Bearer "$access_token -
adminロールを持つユーザーのみがhttp://localhost:8080/api/adminエンドポイントにアクセスできます。 以前に発行されたアクセストークンを使用してこのエンドポイントにアクセスしようとすると、サーバーから403レスポンスが返されます。
curl -v -X GET \ http://localhost:8080/api/admin \ -H "Authorization: Bearer "$access_token -
管理エンドポイントにアクセスするには、
adminユーザーのトークンを取得します。
export access_token=$(\ curl --insecure -X POST http://localhost:8180/realms/quarkus/protocol/openid-connect/token \ --user backend-service:secret \ -H 'content-type: application/x-www-form-urlencoded' \ -d 'username=admin&password=admin&grant_type=password' | jq --raw-output '.access_token' \ ) Dev Services for Keycloak に依存するインテグレーションテストの作成に関する詳細は、「OpenID Connect (OIDC) ベアラートークン認証」ガイドの Dev Services for Keycloak セクションを参照してください。