The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

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.9

  • 動作するコンテナランタイム(Docker, Podman)

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • jq コマンドラインプロセッサーツール

アーキテクチャー

この例では、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 プロジェクトを作成するには、次のコマンドを使用します。

コマンドラインインタフェース
quarkus create app org.acme:security-openid-connect-quickstart \
    --extension='oidc,rest-jackson' \
    --no-code
cd security-openid-connect-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.21.0:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=security-openid-connect-quickstart \
    -Dextensions='oidc,rest-jackson' \
    -DnoCode
cd security-openid-connect-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

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
Maven
./mvnw quarkus:add-extension -Dextensions='oidc'
Gradle
./gradlew addExtension --extensions='oidc'

これにより、ビルドファイルに次の内容が追加されます。

pom.xml
<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-oidc</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-oidc")

アプリケーションの記述

  1. 次の例に示すように、通常の 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;
            }
        }
    }
  2. 次の例に示すように、/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) 設定プロパティー ガイドを参照してください。

Keycloakサーバーの起動と設定

  1. レルム設定ファイル をクラスパス (target/classes ディレクトリー) に配置し、開発モードで実行する際に自動的にインポートされるようにします。 すでに 完全なソリューション をビルド済みの場合は、このレルムファイルはビルド時にクラスパスに追加されるため、この手順は必要ありません。

    アプリケーションを開発モードで実行するときは、Keycloak サーバーを起動しないでください。Dev Services for Keycloak がコンテナーを起動します。 詳細は、アプリケーションを開発モードで実行する セクションを参照してください。

  2. Keycloak サーバーをが起動するには、Docker を使用して次のコマンドを実行します。

    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
    • keycloak.version がバージョン 26.1.3 以降に設定されている場合。

  3. Keycloak サーバーには localhost:8180 からアクセスできます。

  4. Keycloak 管理コンソールにアクセスするには、次のログイン認証情報を使用して admin ユーザーとしてログインします。

    • ユーザー名: admin

    • パスワード: admin

  5. 新しいレルムを作成するには、アップストリームコミュニティーリポジトリーから レルム設定ファイル をインポートします。

詳細は、Keycloak ドキュメントの 新しいレルムの作成と設定 を参照してください。

Keycloak Admin Client を使用してアプリケーションから Keycloak サーバーを設定するには、セットアップに基づいて次のいずれかのエクステンションを含めます。

  • Quarkus REST の場合: quarkus-restquarkus-rest-client、またはその両方を使用している場合は、quarkus-keycloak-admin-rest-client エクステンションを含めます。

  • RESTEasy Classic の場合: quarkus-resteasyquarkus-resteasy-client、またはその両方を使用している場合は、quarkus-keycloak-admin-resteasy-client エクステンションを含めます。

  • REST レイヤーが明示的に使用されていない場合: quarkus-keycloak-admin-rest-client エクステンションを含めることを推奨します。

これらのガイドラインは、REST サーバー、REST クライアント、またはその両方で作業しているかどうかに関係なく、Keycloak Admin Client と REST フレームワークをシームレスに統合できるようにします。

詳細は、Quarkus Keycloak Admin Client ガイドを参照してください。

アプリケーションを開発モードで実行する

  1. 開発モードでアプリケーションを実行するには、次のコマンドを実行します。

    CLI
    quarkus dev
    Maven
    ./mvnw quarkus:dev
    Gradle
    ./gradlew --console=plain quarkusDev
  2. /q/dev-ui にある Dev UI を開きます。 次に、OpenID Connect カードで、 Keycloak provider リンクをクリックします。

  3. OpenID Connect Dev UI によって提供される Single Page Application にログインするように求められたら、次の手順を実行します。

    • user ロールを持つ alice (パスワード: alice) としてログインします。

      • /api/admin にアクセスすると、ステータスコード 403 が返されます。

      • /api/users/me にアクセスすると、ステータスコード 200 が返されます。

    • ログアウトし、adminuser の両方のロールを持つ admin (パスワード: admin) として再度ログインします。

      • /api/admin にアクセスすると、ステータスコード 200 が返されます。

      • /api/users/me にアクセスすると、ステータスコード 200 が返されます。

JVM モードでアプリケーションを実行する

開発モードが完了したら、アプリケーションを標準の Java アプリケーションとして実行できます。

  1. アプリケーションをコンパイルします。

    CLI
    quarkus build
    Maven
    ./mvnw install
    Gradle
    ./gradlew build
  2. アプリケーションを実行します。

    java -jar target/quarkus-app/quarkus-run.jar

ネイティブモードでアプリケーションを実行する

この同じデモを、変更を加えずにそのままネイティブモードにコンパイルできます。 これは、実稼働環境に JVM をインストールする必要がなくなることを意味します。 ランタイムテクノロジーは生成されたバイナリーに組み込まれ、必要最小限のリソースで実行できるように最適化されています。

コンパイルには少し時間がかかるため、この手順はデフォルトで無効になっています。

  1. native プロファイルを有効にして、アプリケーションを再度ビルドします。

    CLI
    quarkus build --native
    Maven
    ./mvnw install -Dnative
    Gradle
    ./gradlew build -Dquarkus.native.enabled=true
  2. しばらく待ってから、次のバイナリーを直接実行します。

    ./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' \
 )

quarkus.oidc.authentication.user-info-required プロパティーが true に設定され、UserInfo をリクエストするためにアクセストークンの使用が要求される場合、トークン付与リクエストコマンドに scope=openid クエリーパラメーターを追加する必要があります。次に例を示します。

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&scope=openid' | 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 セクションを参照してください。

関連コンテンツ