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

Auth0 OpenID Connect プロバイダーを使用して Quarkus Web アプリケーションを保護する

Quarkus Security は、 quarkus-oidc エクステンションを使用して包括的な OpenID Connect (OIDC) および OAuth2 のサポートを提供し、 認可コードフローベアラートークン の両方の認証メカニズムをサポートします。

Quarkus を使用すると、 KeycloakOktaAuth0 などの OIDC プロバイダーや、その他の よく知られたソーシャル OIDC および OAuth2 プロバイダー を簡単に設定できます。

Quarkus OpenID Connect エクステンション (quarkus-oidc) を Auth0 OIDC プロバイダーと組み合わせて使用し、API エンドポイントを保護する方法について説明します。

Auth0 アプリケーションの作成

Auth0 ダッシュボードに移動し、通常の Web アプリケーションを作成します。 例えば、 QuarkusAuth0 という Auth0 アプリケーションを作成します。

Create Auth0 application
結果

Auth0 アプリケーションは、クライアント ID、シークレット、HTTPS ベースのドメインを使用して作成されます。 次のステップで Quarkus の設定を完了するために必要となるため、これらのプロパティーをメモしておいてください。

Created Auth0 application

次に、Auth0 ダッシュボードにいる間に、アプリケーションにユーザーを追加します。

Add Auth0 application users

Auth0 アプリケーションの作成と設定が完了しましたので、Quarkus エンドポイントの作成と設定を開始する準備ができました。 次のステップでは、引き続き Auth0 アプリケーションの設定と更新も行います。

Quarkus アプリケーションの作成

次の Maven コマンドを使用して、Quarkus OIDC エクステンションで保護できる Quarkus REST (旧称 RESTEasy Reactive) アプリケーションを作成します。

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

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

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

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.35.1:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=quarkus-auth0 \
    -Dextensions='rest,oidc' \
    -DnoCode
cd quarkus-auth0

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

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=quarkus-auth0"

アプリケーションワークスペースを作成し、お気に入りの IDE にインポートします。 認証されたユーザーのみがアクセスできる Jakarta REST エンドポイントを追加しましょう。

package org.acme;

import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.IdToken;
import io.quarkus.security.Authenticated;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    @IdToken                                        (1)
    JsonWebToken idToken;

    @GET
    @Authenticated                                  (2)
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + idToken.getName();
    }
}
1 注入された JsonWebToken (JWT) Bean には @IdToken 修飾子があります。これは、アクセストークンではなく OIDC ID トークン を表します。 IdToken は、OIDC 認可コードフロー中に認証された現在のユーザーに関する情報をクレームの形式で提供し、 JsonWebToken API を使用してこれらのクレームにアクセスできます。
2 io.quarkus.security.Authenticated アノテーションが hello() メソッドに追加され、認証されたユーザーのみがアクセスできるようになります。

認可コードフロー中に取得されたアクセストークンは、ID トークンとともにエンドポイントによって直接使用されるのではなく、現在認証されているユーザーに代わってダウンストリームサービスにアクセスする場合にのみ使用されます。 「アクセストークン」に関する詳細は、このチュートリアルの後半で説明します。

以前に作成した Auth0 アプリケーションのプロパティーを使用して、Quarkus の application.properties ファイルで OIDC を設定します。

# Make sure the application domain is prefixed with 'https://'
quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=web-app
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

このステップを完了すると、Quarkus は Auth0 アプリケーションのドメイン、クライアント ID、およびシークレットを使用するように設定されました。 quarkus.oidc.application-type=web-app プロパティーを設定すると、Quarkus は OIDC 認可コードフローを使用するように指示されますが、このチュートリアルの後半では他のメソッドについても説明します。

エンドポイントアドレスは http://localhost:8080/hello となり、これは Auth0 アプリケーションで許可されたコールバック URL として登録する必要があります。

Auth0 allowed callback URL

このステップを完了した後、ブラウザーから Quarkus http://localhost:8080/hello エンドポイントにアクセスすると、認証が完了した後に Auth0 によって同じアドレスにリダイレクトされます。

デフォルトでは、Quarkus は現在のリクエストパスをコールバックパスとして自動的に使用します。 しかし、Quarkus の quarkus.oidc.authentication.redirect-path プロパティーを設定することで、デフォルトの動作をオーバーライドし、特定のコールバックパスを設定できます。

実稼働環境では、アプリケーションの URL 空間が大きくなり、複数のエンドポイントアドレスが利用可能になることがほとんどです。 そのような場合、以下の設定例に示すように、専用のコールバック (リダイレクト) パスを設定し、この URL をプロバイダーのダッシュボードに登録できます。

quarkus.oidc.authentication.redirect-path=/authenticated-welcome

この例のシナリオでは、Quarkus は Auth0 からのリダイレクトを受け入れ、認可コードフローを完了し、セッション Cookie を作成した後、 /authenticated-welcome を呼び出します。 認証に成功したユーザーは、再度認証することなく、保護されたアプリケーションスペースの他の部分にもアクセスできます。例えば、エンドポイントコールバックメソッドは JAX-RS API を使用して、セッション Cookie が検証される保護されたアプリケーションの他の部分にユーザーをリダイレクトできます。

これで、エンドポイントのテストを開始する準備ができました。

Quarkus エンドポイントをテストする

開発モードで Quarkus を起動します。

$ mvn quarkus:dev

このチュートリアルの中で、Quarkus を手動で開発モードで起動する必要があるのはこの時だけです。 このチュートリアルの残りのセクションでの設定およびコード更新のステップは、Quarkus によって自動的に監視および処理され、手動でアプリケーションを再起動する必要はありません。

ブラウザーを開き、 http://localhost:8080/hello にアクセスします。

Auth0 にリダイレクトされ、ログインを求められます。

Auth0 Login

そして、 QuarkusAuth0 アプリケーションがあなたのアカウントにアクセスすることを認可します。

Auth0 Authorize

最後に、Quarkus エンドポイントにリダイレクトされ、以下のレスポンスが返されます。 Hello, auth0|60e5a305e8da5a006aef5471

現在のユーザー名が返されないことに注意してください。 この動作が発生する理由の詳細については、「OpenID Connect (OIDC) の Dev Services と UI」ガイドの すべての OpenID Connect プロバイダーの Dev UI セクションと次のセクションで説明されているように、OIDC Dev UI を使用して確認できます。

OIDC Dev UI で Auth0 トークンを確認する

Quarkus は優れた Dev UI エクスペリエンスを提供します。 特に、Quarkus は Keycloak コンテナーを使用した OIDC エンドポイントの開発とテストに対する組み込みサポートを提供します。 Quarkus の quarkus.oidc.auth-server-url 設定プロパティーに OIDC プロバイダーのアドレスが指定されていない場合、 DevService for Keycloak が自動的に起動され、使用されます。

プロバイダーがすでに設定されている場合でも、Quarkus OIDC Dev UI を引き続き使用できます。 設定を更新するには、次の手順を使用します。

まず、次のように Quarkus アプリケーションタイプを web-app から hybrid に変更します。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid (1)
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}
1 OIDC Dev UI が現在 SPA (シングルページアプリケーション) モードのみをサポートしているため、アプリケーションタイプは hybrid に変更されます。 OIDC Dev UI シングルページアプリケーションは、独自の JavaScript を使用してユーザーを OIDC プロバイダーに認証し、アクセストークンをベアラートークンとして使用して、サービスとして Quarkus エンドポイントにアクセスします。

通常、Quarkus は Bearer トークン認証をサポートするために quarkus.oidc.application-type=service で設定する必要がありますが、 hybrid アプリケーションタイプもサポートしているため、認可コードフローとベアラートークンフローの両方を同時にサポートできます。

Auth0 アプリケーションを設定して、OIDC Dev UI へのコールバックを許可する必要もあります。 以下の URL 形式を使用してください。

  • この例では、 ${provider-name}auth0 です

Auth0 Allowed Callbacks

これで Auth0 で OIDC Dev UI を使用する準備ができました。

ブラウザーセッションで http://localhost:8080/q/dev/ を開きます。Auth0 プロバイダー SPA にリンクする OpenID Connect カードが以下のように表示されます。

Auth0 DevUI

Auth0 provider、次に Login into Single Page Application をクリックします。

Auth0 DevUI Login to SPA

ログインのために Auth0 にリダイレクトされます。 その後、次のように、OIDC Dev UI ダッシュボードにリダイレクトされます。

Auth0 DevUI Dashboard Without Name

ここでは、エンコードおよびデコードされた ID トークンとアクセストークンを確認し、それをクリップボードにコピーしたり、サービスエンドポイントのテストに使用したりできます。後でエンドポイントをテストしますが、ここではまず ID トークンを確認します。

Auth0 IdToken without name

ご覧のとおりユーザー名を表すクレームはありませんが、 sub (subject) クレームを確認すると、その値が、ブラウザーから直接 Quarkus エンドポイントにアクセスした際にレスポンスとして取得した値 (auth0|60e5a305e8da5a006aef5471) と一致することがわかります。

これを修正するには、認証プロセス中に標準の OIDC profile スコープを要求するように Quarkus を設定します。これにより、ID トークンにさらに多くの情報が含まれるようになります。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

quarkus.oidc.authentication.scopes=profile (1)
1 デフォルトの openid スコープに加え、 profile スコープを要求します。

http://localhost:8080/q/dev/ に戻り、 Auth0 へのログインプロセスを繰り返して ID トークンを再度確認すると、 name クレームを含む ID トークンが表示されるはずです。

Auth0 IdToken with name

ブラウザーから Quarkus エンドポイントに直接アクセスすると、名前が返されるはずです。しかし、ブラウザーの Cookie キャッシュをクリアして http://localhost:8080/hello にアクセスしても、再度 Hello, auth0|60e5a305e8da5a006aef5471 が返されます。何が間違っているのでしょうか?

答えは、 org.eclipse.microprofile.jwt.JsonWebToken#getName() 実装の詳細にあります。 MicroProfile MP JWT RBAC の仕様 によると、この実装は MP JWT 固有の upn クレームをチェックし、次に preferred_username を試行し、最後に sub を試行します。これが、ID トークンに name クレームが含まれていても、レスポンスとして Hello, auth0|60e5a305e8da5a006aef5471 が返される理由です。これは、エンドポイント hello() メソッドの実装を、特定のクレーム値を返すように変更することで、簡単に修正できます。

package org.acme;

import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.IdToken;
import io.quarkus.security.Authenticated;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    @IdToken
    JsonWebToken idToken;

    @GET
    @Authenticated
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + idToken.getClaim("name");
    }
}

次にブラウザーのキャッシュをクリアして http://localhost:8080/hello にアクセスすると、ユーザー名が返されます。

ログアウトのサポート

これで、ユーザーは Auth0 を使用して Quarkus にサインインできるようになりました。次は、ユーザー主導のログアウトのサポートが必要になるのではないでしょうか。Quarkus は、 RP-initiatedおよび他の標準的な OIDC ログアウトメカニズム、およびローカルセッションログアウト をサポートしています。

現在、Auth0 は標準の OIDC RP-initiated Logoutをサポートしておらず、検出可能なメタデータにセッション終了エンドポイント URL を提供していませんが、標準のものとほぼ同じように動作する独自のログアウトメカニズムを提供しています。

Quarkus OIDC を使用するとこれを簡単にサポートできます。Auth0 のセッション終了エンドポイント URL を設定し、Quarkus で、 client-id クエリーパラメーターとログアウト後の URL の両方を、 returnTo クエリーパラメーターとしてAuth0 への RRP-initated logoutリダイレクトリクエストに含める必要があります。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}
quarkus.oidc.authentication.scopes=openid,profile

quarkus.oidc.end-session-path=v2/logout (1)
quarkus.oidc.logout.post-logout-uri-param=returnTo (2)
quarkus.oidc.logout.extra-params.client_id=${quarkus.oidc.client-id} (3)
quarkus.oidc.logout.path=/logout (4)
quarkus.oidc.logout.post-logout-path=/hello/post-logout (5)

quarkus.http.auth.permission.authenticated.paths=/logout
quarkus.http.auth.permission.authenticated.policy=authenticated (6)
1 Auth0 はメタデータにセッション終了 URL を含めないため、Auth0 セッション終了エンドポイント URL を手動で設定して補完します。
2 Auth0 は標準の post_logout_redirect_uri クエリーパラメーターを認識せず、代わりに returnTo パラメーターを期待します。
3 Auth0 はログアウトリクエストで client-id を期待します。
4 /logout パスへの認証済みリクエストは、RP 主導型ログアウトリクエストとして処理されます。
5 これは、ログアウトしたユーザーが返されるパブリックリソースです。
6 /logout パスが保護されているようにして下さい。

ここでは、Auth0 セッション終了エンドポイント URL をカスタマイズし、Quarkus に対して、 http://localhost:8080/logout リクエストが現在認証されているユーザーのログアウトをトリガーする必要があることを示しました。 /logout パスについては、それが virtual であり、JAX-RS エンドポイントのどのメソッドでもサポートされていないことに留意する必要があります。これが理由で、Quarkus OIDC が /logout リクエストに反応するためには、設定でこのパスに直接 authenticated HTTP セキュリティーポリシー をアタッチする必要があります。

また、ログアウトしたユーザーをパブリック /hello/post-logout リソースに返すように Quarkus を設定しました。このパスは、Auth0 固有の returnTo クエリーパラメーターとしてログアウトリクエストに含まれています。Quarkus アプリケーションの client-id もログアウト URL に含まれています。

ログアウト後のリダイレクトを受け入れるようにエンドポイントを更新します。

package org.acme;

import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.IdToken;
import io.quarkus.security.Authenticated;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    @IdToken
    JsonWebToken idToken;

    @GET
    @Authenticated
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + idToken.getClaim("name");
    }

    @GET
    @Path("post-logout")
    @Produces(MediaType.TEXT_PLAIN)
    public String postLogout() {
        return "You were logged out";
    }
}

パブリック /hello/post-logout リソースメソッドが追加されたことに注意してください。

ログアウトをテストする前に、ユーザーがログアウトした後の Quarkus へのリダイレクトを許可するように、 Auth0 アプリケーションが設定されていることを確認します。

Auth0 Allowed Logout

ここで、ブラウザーの Cookie キャッシュをクリアし、 http://localhost:8080/hello にアクセスし、Auth0 で Quarkus にログインしてユーザー名を取得し、 http://localhost:8080/logout に移動します。ブラウザーには、 You were logged out というメッセージが表示されます。

次に、 http://localhost:8080/q/dev/ に移動し、Dev UI SPA から Auth0 にログインします。 Logged in as Sergey Beryozkin というテキストの横に、ログアウトを表す記号が表示され、OIDC Dev UI からもログアウトが可能になったことがわかります。

Auth0 Dashboard with name and Logout

OIDC DevUI からのログアウトが機能するためには、Auth0 アプリケーションの許可されたログアウトコールバックのリストを更新して、OIDC DevUI エンドポイントを含める必要があります。

Auth0 Allowed Logouts

次に、OIDC Dev UI から直接ログアウトし、新しいユーザーとしてログインします。必要に応じて、登録済みの Auth0 アプリケーションにさらにユーザーを追加します。

ロールベースのアクセス制御

Auth0 を使用して認証されたユーザーが Quarkus エンドポイントにアクセスできることを確認しました。

次の手順では、ロールベースのアクセス制御 (RBAC) を導入して、 admin など特定のロールを持つユーザーのみがエンドポイントにアクセスできるようにします。

以下の 権限ベースのアクセス制御 セクションも参照してください。

デフォルトで、Auth0 トークンにはロールを含むクレームは含まれていないため、まず、トークンにロールを追加するカスタムアクションを使用して、 Auth0 アプリケーションの Login フローをカスタマイズする必要があります。 Auth0 ダッシュボードで Actions/Flows/Login を選択し、 Add Action/Build Custom を選択し、 AddRoleClaim という名前を付けます。

Auth0 Add Role Action

そこに次のアクションスクリプトを追加します。

exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://quarkus-security.com';
  if (event.authorization) {
    api.idToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
    api.accessToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
  }
};

カスタム Auth0 クレームは namespace で修飾される必要があるため、ロールを含むクレームの名前は https://quarkus-security.com/roles になります。前のセクションで分析した ID トークンのコンテンツを確認すると、このクレームがどのように表現されているかがわかります。以下はその例です。

{
  "https://quarkus-security.com/roles": [
      "admin"
  ]
}

Auth0 のログインフロー図は次のようになります。

Auth0 Login Flow

Auth0 アプリケーションに登録されているユーザーに、 admin などのロールを追加する必要があります。

admin ロールを作成します。

Auth0 Create Role

それを登録済みユーザーに追加します。

Auth0 Add Role to User

次に、Quarkus エンドポイントを更新して、 admin ロールを持つユーザーのみがエンドポイントにアクセスできるようにします。

package org.acme;

import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.IdToken;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    @IdToken
    JsonWebToken idToken;

    @GET
    @RolesAllowed("admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + idToken.getClaim("name");
    }

    @GET
    @Path("post-logout")
    @Produces(MediaType.TEXT_PLAIN)
    public String postLogout() {
        return "You were logged out";
    }
}

http://localhost:8080/hello を開き、Auth0 に対して認証すると 403 が発生します。ここでは、Quarkus OIDC が Auth0 トークンのどのクレームがロール情報を表しているか認識していないため、 403 が発生します。デフォルトでは groups クレームがチェックされますが、ここでは Auth0 トークンに "https://quarkus-security.com/roles" クレームがあることが期待されます。

RBAC を適用するためにどのクレームをチェックする必要があるかを Quarkus OIDC に指示して修正します。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.authentication.scopes=profile
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

quarkus.oidc.roles.role-claim-path="https://quarkus-security.com/roles" (1)

# Logout
quarkus.oidc.end-session-path=v2/logout
quarkus.oidc.logout.post-logout-uri-param=returnTo
quarkus.oidc.logout.extra-params.client_id=${quarkus.oidc.client-id}
quarkus.oidc.logout.path=/logout
quarkus.oidc.logout.post-logout-path=/hello/post-logout
quarkus.http.auth.permission.authenticated.paths=/logout
quarkus.http.auth.permission.authenticated.policy=authenticated
1 カスタムロールクレームを指します。クレームは namespace で修飾されているため、ロールクレームへのパスは二重引用符で囲まれます。

ブラウザーの Cookie キャッシュをクリアし、再度 http://localhost:8080/hello にアクセスし、Auth0 に対して認証して期待されるユーザー名を取得します。

不透明 Auth0 アクセストークンを使用して Quarkus にアクセスする

このセクションでは主に、Auth0 JWT アクセストークンではなく、 不透明 ベアラー Auth0 アクセストークンを受け入れるように Quarkus を調整する方法を説明します。なぜなら、認可コードフローで発行される Auth0 アクセストークンはデフォルトで不透明であり、すでに ID トークンで提供されている現行ユーザーの情報に加え、 UserInfo をリクエストするためにしか使用できないためです。多くの OIDC および OAuth2 プロバイダーは不透明アクセストークンしか発行しないため、不透明トークンの検証方法を理解すると役立ちます。

Auth0 と Quarkus を設定して認可コードアクセストークンを JWT フォーマットで発行し、サービスエンドポイントに伝播させる方法の詳細は、アクセストークンをマイクロサービスに伝播する セクションとJWT形式のアクセストークン セクションを参照してください。

これまで、OIDC 認可コードフローを使用して Quarkus エンドポイントのみをテストしてきました。このフローでは、ブラウザーを使用して Quarkus エンドポイントにアクセスし、Quarkus 自体が認可コードフローを管理します。ユーザーは Auth0 にリダイレクトされてログインし、Quarkus に再度リダイレクトされます。その後 Quarkus が ID トークン、アクセストークン、およびリフレッシュトークンのコードを交換してフローを完了し、ユーザー認証の成功を表す ID トークンを処理します。この時点でアクセストークンは使用されません。前述のとおり、Quarkus が認可コードフローでアクセストークンを使用するのは、認証済の現行ユーザーに代わってダウンストリームサービスにアクセスする場合に限られます。

しかし、開発した Quarkus エンドポイントも ベアラー アクセストークンを受け入れる必要があると想像してみてください。このエンドポイントにそれを伝播している他の Quarkus エンドポイントかもしれませんし、アクセストークンを使用して Quarkus エンドポイントにアクセスする SPA かもしれません。その場合、すでに ID トークンの分析に使用した Quarkus OIDC Dev UI SPA は、SPA が使用できるアクセストークンを使用して Quarkus エンドポイントをテストするのに最適です。

再度 http://localhost:8080/q/dev-ui にアクセスし、 OpenId Connect カードを選択して Auth0 にログインし、アクセストークンの内容を確認します。

Auth0 DevUI Access Token

このアクセストークンは、前述の ID トークンとは異なり、Quarkus が直接検証することはできません。これは、アクセストークンが JWS (署名済み) フォーマットではなく JWE (暗号化済み) フォーマットであるためです。デコードされたトークンヘッダーから、Auth0 のみが知る秘密鍵で直接暗号化されているため、Quarkus はその内容を復号化できないことがわかります。Quarkus の観点から見ると、このアクセストークンは 不透明 であり、Quarkus は Auth0 の公開非対称検証キーを使用してこれを検証できません。

確認するには、 Test Service 領域の Service Address/hello と入力し、 With Access Token を押すと、HTTP 401 ステータスが返されます。

Auth0 Dev UI Test Access token 401

Quarkus がそのようなアクセストークンを受け入れるには、2 つのオプションのいずれかを利用できる必要があります。最初のオプションは、プロバイダーのイントロスペクションエンドポイントを使用して、不透明なトークンをリモートでイントロスペクトすることです。トークンのイントロスペクションは通常 OAuth2 レベルでサポートされ、 OIDCOAuth2 上に構築されているため、Keycloak などの一部の OIDC プロバイダーもトークンのイントロスペクションをサポートします。ただし、Auth0 はトークンのイントロスペクションをサポートしません。これは、公開されている Auth0 メタデータを見ることで確認できます。設定済みの Auth0 プロバイダーのアドレスに /.well-known/openid-configuration を追加し、結果の URL https://dev-3ve0cgn7.us.auth0.com/.well-known/openid-configuration を開いてみてください。Auth0 にイントロスペクションエンドポイントがないことがわかります。

Auth0 Well Known Config

したがって、もう 1 つのオプションである間接的なアクセストークン検証 (アクセストークンを使用して Auth0 から UserInfo を取得する) を使用して、不透明な Auth0 トークンを受け入れ、検証することができます。OIDC プロバイダーは UserInfo を発行する前にアクセストークンを検証する必要があり、Auth0 には UserInfo エンドポイントがあるため、このオプションが機能します。

それでは、アクセストークンを使用して UserInfo を取得することで検証するように、Quarkus を設定しましょう。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.authentication.scopes=profile
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

# Point to the custom roles claim
quarkus.oidc.roles.role-claim-path="https://quarkus-security.com/roles"

# Logout
quarkus.oidc.end-session-path=v2/logout
quarkus.oidc.logout.post-logout-uri-param=returnTo
quarkus.oidc.logout.extra-params.client_id=${quarkus.oidc.client-id}
quarkus.oidc.logout.path=/logout
quarkus.oidc.logout.post-logout-path=/hello/post-logout
quarkus.http.auth.permission.authenticated.paths=/logout
quarkus.http.auth.permission.authenticated.policy=authenticated

quarkus.oidc.token.verify-access-token-with-user-info=true (1)
1 アクセストークンを使用して UserInfo をリクエストすることで、アクセストークンを間接的に検証します。

ID token ではなく UserInfo を期待するように、エンドポイントコードを更新します。

package org.acme;

import io.quarkus.oidc.UserInfo;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    UserInfo userInfo;

    @GET
    @RolesAllowed("admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + userInfo.getName();
    }

    @GET
    @Path("post-logout")
    @Produces(MediaType.TEXT_PLAIN)
    public String postLogout() {
        return "You were logged out";
    }
}

このコードは、認可コードフローとベアラーアクセストークンフローの両方で機能するようになります。

アクセストークンを確認した OIDC Dev UI に移動し、 Test Service 領域の Service Address/hello と入力し、 With Access Token を押すと 200 が返されます。

Auth0 Dev UI Test Access token

実際に動作することを確認するには、テストエンドポイントを更新して、 @RolesAllowed("user")user ロールのみを許可します。再度 OIDC Dev UI からエンドポイントにアクセスすると、HTTP 403 エラーが発生します。コードを @RolesAllowed("admin") に戻すと、再び期待どおりの HTTP 200 ステータスが返されます。

不透明なアクセストークンを間接的に検証する場合 (つまり、それを使用して UserInfo をリクエストする場合)、Quarkus はロール情報のソースとして UserInfo を使用します (存在する場合)。たまたま Auth0 は、以前に作成されたカスタムロールクレームを UserInfo レスポンスにも含めます。

このセクションの冒頭で既に述べたように、このセクションの主な目的は、Quarkus が不透明なアクセストークンを検証する方法を説明することです。一般に、フロントエンドの JAX-RS エンドポイントまたは SPA が UserInfo の取得を信頼できるサービスに委譲することを望まない限り、 UserInfo の取得のみを目的とするアクセストークンをサービスに伝播することは避けるべきです。

Auth0 アクセストークンを扱う推奨される方法については、以下の アクセストークンをマイクロサービスに伝播する セクションと JWT形式のアクセストークン セクション を参照してください。

通常、リモートサービスにアクセスするためにアクセストークンを使用しますが、OIDC DevUI SPA ダッシュボードでは ID トークンでテストするオプションも提供されています。このオプションは、SPA がエンドポイントに委譲して ID トークンから何らかの情報を検証および取得し、SPA が使用するケースをエミュレートするためにのみ利用できます。ただし、ID トークンは OIDC DevUI によってベアラートークンとしてエンドポイントに送信されます。ほとんどの場合、アクセストークンでのテストを推奨します。

サービスパスを手動で入力する代わりに、OIDC DevUI の SwaggerUI または GraphQL を使用してサービスをテストできます。 たとえば、以下を追加すると、

<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>

アプリケーションの pom に Swagger リンクが表示されます。

Auth0 Dev UI Test with Swagger

Swagger リンクをクリックして、サービスのテストを開始します。

アクセストークンをマイクロサービスに伝播する

OIDC 認可コードフローを使用し、ID トークンと UserInfo の両方を使用してユーザー情報にアクセスできるようになりました。一般的な次のタスクは、現在の Auth0 アクセストークンを伝播して、現行の認証済みユーザーに代わってダウンストリームサービスにアクセスすることです。

実際、注入された UserInfo を示す最後のコード例は、アクセストークン伝播の具体的な例です。この場合、Quarkus は Auth0 アクセストークンを Auth0 UserInfo エンドポイントに伝播して UserInfo を取得します。Quarkus は、ユーザーが何もしなくてもこれを実行します。

しかし、アクセストークンを一部のカスタムサービスに伝播させる場合はどうでしょうか。Quarkus では、認可コードフローとベアラートークンフローの両方で非常に簡単にこれを実現できます。ベアラートークンアクセスを必要とするサービスを呼び出すための REST クライアントインターフェイスを作成し、それに @AccessToken アノテーションを付けるだけで、Auth0 ベアラーアクセストークンとしてフロントエンドエンドポイントに到着するアクセストークン、または Auth0 認可コードフローの完了後に Quarkus が取得したアクセストークンが、ターゲットマイクロサービスに伝播されます。これ以上簡単にはならないほど簡単です。

アクセストークンの伝播の例については、このチュートリアルの以下のセクションを参照してください。 トークンの伝播の詳細については、 OIDC トークンの伝播 を参照してください。

JWT形式のアクセストークン

Quarkus OIDC が 不透明 Auth0 アクセストークンを使用して Quarkus にアクセスする をどのように処理できるかについては既に詳しく見てきましたが、UserInfo の確認以外に現行の認証済みユーザーに代わって有用な何かを行うマイクロサービスに、Auth0 の不透明なトークンを伝播することは望ましくありません。

フロントエンドの Quarkus アプリケーションが認可コードフローのアクセストークンを伝播してアクセスするマイクロサービスは、Auth0 ダッシュボードでは API として表されます。これを Applications/APIs に追加してみましょう。

Auth0 API

作成された QuarkusAuth0APIhttps://quarkus-auth0 識別子は、この API の audience として機能します。Auth0 への認可コードフローリダイレクトでこのオーディエンスをクエリーパラメーターとして提供すると、Auth0 は必ず JWT フォーマットでアクセストークンを発行するようになります。

API マイクロサービス

OIDC トークンの伝播と REST クライアントをサポートするために、以下の依存関係をプロジェクトに追加します。

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest-client-jackson</artifactId>
</dependency>
<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-rest-client-oidc-token-propagation</artifactId>
</dependency>

ApiEchoService サービスクラスを作成します。

package org.acme;

import io.quarkus.security.Authenticated;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/echo")
public class ApiEchoService {

    @POST
    @Authenticated
    @Produces(MediaType.TEXT_PLAIN)
    public String echoUserName(String username) {
        return username;
    }
}

そして、Auth0 から公開検証キーのみを取得する OIDC service アプリケーションとして設定します。 このマイクロサービスの設定は、次の 1 行のみとなるはずです。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com

これだけで、OIDC service アプリケーションは Auth0 公開検証キーを取得し、それを使用して JWT フォーマットの Auth0 アクセストークンを検証できます。

このチュートリアルでは、認可コードとベアラートークン認証フローの両方を処理できる OIDC hybrid アプリケーションを既に設定しています。本番環境ではマイクロサービスを別のサーバーとして実行しますが、ここでは簡潔にするために、 ApiEchoServicequarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com のみを含む独自の設定を持つ 2 番目のサーバーとして起動する必要はありません。そのため、Auth0 開発テナントアドレスが既に設定されている現在の設定が再利用されます。

hybrid OIDC アプリケーションタイプは、GreetingResource への http://localhost:8080/hello リクエストが認可コードフローを開始する一方、GreetingResource によって開始された ApiEchoService への http://localhost:8080/echo リクエストによって、認可コードフロートークンが伝播され、ベアラー JWT アクセストークンとして ApiEchoService によって受け入れられるようにします。

次に、 ApiEchoService を表す REST クライアントインターフェイスを追加します。

package org.acme;

import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import io.quarkus.oidc.token.propagation.common.AccessToken;

@RegisterRestClient
@AccessToken (1)
@Path("/echo")
public interface ApiEchoServiceClient {

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    String echoUserName(String username);
}
1 アクセストークンを HTTP Authorization: Bearer accesstoken ヘッダーとして伝播します。

さらに、以前に作成した Quarkus フロントエンドアプリケーション GreetingResource の設定を更新して、認可コードフローのアクセストークン (ID トークンではなく) に ApiEchoService をターゲットとする aud (オーディエンス) クレームを組み込むようにリクエストし、 ApiEchoService REST クライアントのベース URL を設定します。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.authentication.scopes=profile
quarkus.oidc.authentication.extra-params.audience=https://quarkus-auth0 (1)
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

# Point to the custom roles claim
quarkus.oidc.roles.role-claim-path="https://quarkus-security.com/roles"

# Logout
quarkus.oidc.end-session-path=v2/logout
quarkus.oidc.logout.post-logout-uri-param=returnTo
quarkus.oidc.logout.extra-params.client_id=${quarkus.oidc.client-id}
quarkus.oidc.logout.path=/logout
quarkus.oidc.logout.post-logout-path=/hello/post-logout
quarkus.http.auth.permission.authenticated.paths=/logout
quarkus.http.auth.permission.authenticated.policy=authenticated

quarkus.oidc.token.verify-access-token-with-user-info=true

org.acme.ApiEchoServiceClient/mp-rest/url=http://localhost:${port} (2)

quarkus.test.integration-test-profile=test
%prod.port=8080
%dev.port=8080
%test.port=8081
1 Quarkus から Auth0 への認可コードフローのリダイレクト中に、追加の audience クエリーパラメーターを Auth0 認可エンドポイントに渡します。 これにより、アクセストークンが JWT フォーマットで発行され、 https://quarkus-auth0 を含む aud (オーディエンス) クレームが確実に組み込まれます。
2 ApiEchoServiceClientApiEchoService エンドポイントを指すようにします。org.acme.ApiEchoServiceClient/mp-rest/url=http://localhost:${port} プロパティーの HTTP ポートはパラメーター化されており、開発モード、テストモード、本番モードの使用中に正しい URL が構築されるようにします。

最後に、 ApiEchoService がユーザー名をエコーするようにリクエストするように、 GreetingResource を更新します。

package org.acme;

import io.quarkus.oidc.UserInfo;
import io.quarkus.security.Authenticated;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RestClient;

@Path("/hello")
public class GreetingResource {
    @Inject
    @RestClient
    ApiEchoServiceClient echoClient; (1)

    @Inject
    UserInfo userInfo;

    @GET
    @RolesAllowed("admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello, " + echoClient.echoUserName(userInfo.getName()); (2)
    }

    @GET
    @Path("post-logout")
    @Produces(MediaType.TEXT_PLAIN)
    public String postLogout() {
        return "You were logged out";
    }
}
1 ApiEchoServiceClient REST クライアントを注入します。
2 ApiEchoServiceClient を使用してユーザー名をエコーします。

ブラウザーを開き、 http://localhost:8080/hello にアクセスすると、ブラウザーに自分の名前が表示されます。

http://localhost:8080/q/dev-ui に移動し、 OpenId Connect カードを選択し、Auth0 にログインしてアクセストークンの内容を確認します。

Auth0 DevUI JWT Access Token

ご覧のとおり、不透明 Auth0 アクセストークンを使用して Quarkus にアクセスする セクションで示したようにアクセストークンは暗号化されなくなり、実際には JWT フォーマットになりました。

権限ベースのアクセス制御

ロールベースのアクセス制御 セクションでは、Quarkus でユーザーロールを含む namespace で修飾されたクレームをチェックする方法と、その情報を使用してロールベースのアクセス制御を適用する方法について説明しました。Auth0 は既に、ID トークンとアクセストークンの両方にカスタムロールクレームを追加するように設定されています。

ただし、権限ベースのアクセス制御は、アクセストークンがフロントエンドのエンドポイントからマイクロサービスに伝播される場合に、より適しています。この場合、トークンがユーザーが特定のロールにあることを保証するのではなく、特定のアクセストークンがこのサービスで具体的なアクションを実行することを許可されているかどうかをマイクロサービスがチェックします。たとえば、管理者ロールにあるからといって、ユーザーがこのマイクロサービスのコンテンツの一部に対する読み取りおよび書き込みアクセスを許可されるとは限りません。

権限ベースのアクセス制御の制約を ApiEchoService に適用する方法を見てみましょう。

Auth0 ダッシュボードに移動し、 QuarkusAuth0API API に echo:name 権限を追加します。

Auth0 API permissions

echo:name 権限は、認可コードフロー中にこのスコープもリクエストされた場合、標準の OAuth2 scope クレーム値としてアクセストークンに含まれます。次のように設定を更新します。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.authentication.scopes=profile,echo:name (1)
quarkus.oidc.authentication.extra-params.audience=https://quarkus-auth0
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

# Point to the custom roles claim
quarkus.oidc.roles.role-claim-path="https://quarkus-security.com/roles"

# Logout
quarkus.oidc.end-session-path=v2/logout
quarkus.oidc.logout.post-logout-uri-param=returnTo
quarkus.oidc.logout.extra-params.client_id=${quarkus.oidc.client-id}
quarkus.oidc.logout.path=/logout
quarkus.oidc.logout.post-logout-path=/hello/post-logout
quarkus.http.auth.permission.authenticated.paths=/logout
quarkus.http.auth.permission.authenticated.policy=authenticated

quarkus.oidc.token.verify-access-token-with-user-info=true

org.acme.ApiEchoServiceClient/mp-rest/url=http://localhost:8080
1 認可コードフロー中に、追加の echo:name スコープがリクエストされます。

ここで、権限ベースのアクセス制御を適用するように ApiEchoService を更新します。

package org.acme;

import io.quarkus.security.PermissionsAllowed;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/echo")
public class ApiEchoService {

    @POST
    @PermissionsAllowed("echo:name")
    @Produces(MediaType.TEXT_PLAIN)
    String echoUserName(String username) {
        return username;
    }
}

Quarkus OIDC は scope クレーム値を現行のセキュリティーアイデンティティーの権限として自動的に関連付けるため、必要なのはこれだけです。

@RolesAllowed アノテーションと @PermissionsAllowed アノテーションを組み合わせることで、Quarkus でロールベースおよび権限ベースの両方のアクセス制御を適用できます。

ブラウザーを開いて http://localhost:8080/hello にアクセスし、ブラウザーに表示される名前を取得します。

権限が正しく適用されていることを確認するには、これを echo.name: @PermissionsAllowed("echo.name") に変更します。ブラウザーのキャッシュをクリアし、 http://localhost:8080/hello に再度アクセスすると、 ApiEchoService によって 403 が報告されます。ここで、権限を @PermissionsAllowed("echo:name") に戻します。

統合テスト

すでに OIDC DevUI SPA を使用して Auth0 にログインし、アクセストークンを使用して Quarkus エンドポイントをテストし、その過程でエンドポイントコードを更新しています。

しかし、テストの実行も重要です。ここでは、Quarkus 継続的テスト 機能を使用して、このチュートリアルを実施する中で開発したエンドポイントと設定をテストする方法を説明します。

次のテストコードから始めます。

package org.acme;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
             .statusCode(200)
             .body(is("Hello, Sergey Beryozkin"));
    }

}

覚えているかもしれませんが、アプリケーションが開発モードで起動されたとき、CLI ウィンドウに次のように表示されました。

Auth0 DevMode started

r を押すと、テストが 403 で失敗していることがわかります。テストはエンドポイントにトークンを送信しないため、これは想定された結果です。

Auth0 test failure 403

テストを修正する前に、OIDC によって保護された Quarkus エンドポイントをテストするために利用可能なオプションを確認しましょう。これらのオプションは、アプリケーションがサポートするフローや、テスト方法によって異なる場合があります。OIDC 認可コードフローを使用するエンドポイントは、 これらのオプションのいずれか を使用してテストでき、ベアラー認証を使用するエンドポイントは、 これらのオプションのいずれか を使用してテストできます。

このように、Auth0 で保護されたエンドポイントのテストは、 Wiremock または @TestSecurity アノテーションを使用して行うことができます。このようなテストを自分で書いてみて、問題が発生した場合はご連絡ください。

ただしこのチュートリアルでは、最近追加された OidcTestClient を使用して、ライブ Auth0 開発テナントを使用するエンドポイントのテストをサポートします。

関連する設定フラグメントを次に示します。

quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
quarkus.oidc.application-type=hybrid
quarkus.oidc.authentication.scopes=profile
quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly
quarkus.oidc.credentials.secret=${client-secret}

実稼働環境では、 %prod. および %test. 修飾子を使用して本番レベルとテストレベルの設定を区別します。ここでは、実際のアプリケーションで上記の設定が %test. から始まり、この設定に %prod. で修飾された Auth0 実稼働テナント設定が含まれると仮定します。

OidcTestClient を使用してこのような設定をテストするには、OAuth2 password または client_credentials グラントのいずれかを使用して、Auth0 開発テナントからトークンを取得する必要があります。ここでは password グラントを試します。Auth0 ダッシュボードに登録されているアプリケーションが password グラントを許可していることを確認してください。

Auth0 password grant

ここで明確にする必要があるのですが、実稼働環境で非推奨の OAuth2 password トークングラントを使用することは推奨されません。ただし、ライブ開発 Auth0 テナントから取得したトークンを使用してエンドポイントをテストする場合には役立ちます。

OidcTestClient は、認可コードフローとベアラー認証の両方をサポートしているため、このチュートリアルで開発したエンドポイントで動作するベアラー認証を受け入れるアプリケーションのテストに使用する必要があります。認可コードフローのみがサポートされている場合は、OIDC WireMock または HtmlUnit を Auth0 開発テナントに対して直接使用する必要があります。後者の場合、 HtmlUnit テストコードは、Auth0 がユーザーにクレデンシャルの入力を要求する方法に合わせる必要があります。もしよろしければ、ドキュメントにある HtmlUnit テストフラグメント をコピーして試してみてください。

ここでは OidcTestClient を使用して、現時点で失敗しているテストを修正します。

まず、次の依存関係を追加する必要があります。

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-test-oidc-server</artifactId>
    <scope>test</scope>
</dependency>
build.gradle
testImplementation("io.quarkus:quarkus-test-oidc-server")

これは、アクセストークンの取得テストに使用できるユーティリティークラス io.quarkus.test.oidc.client.OidcTestClient を提供します (この依存関係は OIDC WireMock サポートも提供します。必要に応じてドキュメントでテストに使用する方法を確認してください)。

次に、テストコードを以下のように更新します。

package org.acme;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

import java.util.Map;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.oidc.client.OidcTestClient;

@QuarkusTest
public class GreetingResourceTest {

    static OidcTestClient oidcTestClient = new OidcTestClient();

    @AfterAll
    public static void close() {
        client.close();
    }

    @Test
    public void testHelloEndpoint() {
        given()
          .auth().oauth2(getAccessToken(`sberyozkin@gmail.com`, "userpassword"))
          .when().get("/hello")
          .then()
             .statusCode(200)
             .body(is("Hello, Sergey Beryozkin"));
    }

    private String getAccessToken(String name, String secret) {
        return oidcTestClient.getAccessToken(name, secret, (1)
            Map.of("audience", "https://quarkus-auth0",
	           "scope", "openid profile"));
    }
}
1 OidcTestClient は、登録済みユーザーの名前とパスワードのいずれか、ならびに audience および scope パラメーターを使用して、アクセストークンを取得するために使用されます。

OidcTestClient は、 Auth0 トークンのエンドポイントのアドレス、クライアント id、およびシークレットを検出します。

もう一度 r を押すと、テストが合格します。

Auth0 test success

ちなみに、必要に応じて DevUI から直接、連続モードでテストを実行することもできます。

Auth0 Continuous testing

本番モード

Auth0 で保護された Quarkus エンドポイントを開発モードで開発およびテストしました。 次のステップでは、アプリケーションを本番モードで実行します。 JVM モードとネイティブモードを選択します。

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

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

コマンドラインインタフェース
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

アプリケーションを実行します。

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

ブラウザーを開いて http://localhost:8080/hello にアクセスし、ブラウザーに表示される名前を取得します。

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

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

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

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

コマンドラインインタフェース
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

次に、以下のバイナリーを直接実行します。

./target/quarkus-auth0-1.0.0-SNAPSHOT-runner

ブラウザーを開いて http://localhost:8080/hello にアクセスし、ブラウザーに表示される名前を取得します。

トラブルシューティング

このチュートリアルで説明された手順は、チュートリアルで説明されたとおりに動作するはずです。すでに認証を完了している場合は、更新後の Quarkus エンドポイントにアクセスする際にブラウザーの Cookie をクリアする必要があることもあります。開発モードで Quarkus アプリケーションを手動で再起動する必要がある可能性もありますが、これは想定されていません。このチュートリアルを完了するのにサポートが必要な場合は、Quarkus チームにお問い合わせください。

まとめ

このチュートリアルでは、同じエンドポイントコードでサポートされている認可コードフローとベアラー認証フローを使用して、Quarkus エンドポイントを quarkus-oidc エクステンションと Auth0 で保護する方法を実演しました。 コードを 1 行も書くことなく、カスタム Auth0 ログアウトフローのサポートを追加し、カスタム Auth0 namespace 修飾子クレームを使用してロールベースのアクセス制御を有効にしました。 マイクロサービス REST クライアントに @AccessToken アノテーションを追加することで、フロントエンドエンドポイントからマイクロサービスエンドポイントにトークンを伝播しました。 マイクロサービスエンドポイントは、 @PermissionsAllowed アノテーションを使用して権限ベースのアクセス制御を有効にしました。 Quarkus 開発モードを使用して、エンドポイントを再起動せずにコードと設定を更新し、OIDC Dev UI を使用して Auth0 トークンを視覚化およびテストしました。 Quarkus の継続的テスト機能を使用して、OIDC Dev UI テストをライブ Auth0 開発テナントに対する統合テストで補完しました。 最後に、アプリケーションを JVM モードとネイティブモードで実行しました。

楽しんでください!