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

JWT RBAC の使用

このガイドでは、Quarkus アプリケーションに SmallRye JWT を統合し、MicroProfile JWT 仕様に準拠した JSON Web Token (JWT) セキュリティーを実装する方法を説明します。 JWT の検証方法、MicroProfile JWT の org.eclipse.microprofile.jwt.JsonWebToken としての表現、およびベアラートークン認証と ロールベースアクセス制御 (RBAC) を使用して Quarkus の HTTP エンドポイントを保護する方法を学びます。

Quarkus の OpenID Connect (quarkus-oidc) エクステンションもベアラートークン認証をサポートしており、 smallrye-jwt を使用してベアラートークンを JsonWebToken として表現します。 詳細については、OIDC ベアラートークン認証 ガイドを参照してください。

Quarkus アプリケーションで OIDC 認可コードフローを使用してユーザーを認証する必要がある場合は、OpenID Connect エクステンションを使用する必要があります。 詳細については、Web アプリケーションを保護するための OIDC コードフローメカニズム を参照してください。

要件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.9

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

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

クイックスタート

ソリューション

アプリケーションを段階的に作成するには、次のセクションの指示に従うことを推奨します。 必要に応じて、完成した例に進むこともできます。

例を利用するには、Git リポジトリーをクローンするか、アーカイブをダウンロードします。

  • リポジトリーをクローンします (git clonehttps://github.com/quarkusio/quarkus-quickstarts.git)。

  • アーカイブ をダウンロードします。

ソリューションは security-jwt-quickstart ディレクトリー にあります。

Maven プロジェクトの作成

まず、以下のコマンドで新規プロジェクトを作成します:

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

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

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

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.19.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=security-jwt-quickstart \
    -Dextensions='rest-jackson,smallrye-jwt,smallrye-jwt-build' \
    -DnoCode
cd security-jwt-quickstart

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

Windowsユーザーの場合:

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

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

このコマンドは、RESTエンドポイントを持つMavenプロジェクトを生成し、MicroProfile JWT RBAC サポートを含む smallrye-jwt エクステンションをインポートします。

If you already have your Quarkus project configured, you can add the smallrye-jwt extension to your project by running the following command in your project base directory:

コマンドラインインタフェース
quarkus extension add smallrye-jwt,smallrye-jwt-build
Maven
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
Gradle
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'

このコマンドは、ビルドファイルに以下の依存関係を追加します。

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

Jakarta REST リソースの調査

RESTエンドポイントを src/main/java/org/acme/security/jwt/TokenSecuredResource.java に以下の内容で作成します。

REST エンドポイント V1
package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; (1)

    @GET
    @Path("permit-all")
    @PermitAll (2)
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx); (3)
    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) { (4)
            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) { (5)
            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName(); (6)
        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt()); (7)
    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
1 JsonWebToken インターフェイスが挿入され、現在の認証済みトークンに関連付けられたクレームにアクセスできるようになります。このインターフェイスは java.security.Principal を継承します。
2 @PermitAll は標準の Jakarta セキュリティーアノテーションです。これは、認証されているかどうかに関係なく、指定されたエンドポイントがすべての呼び出し元からアクセスできることを示します。
3 Jakarta REST SecurityContext は、リクエストのセキュリティー状態を検査するために挿入されます。 getResponseString() 関数はレスポンスを生成します。
4 リクエストのユーザー/呼び出し元の Principal を null と照合して、呼び出しが安全でないかどうかを確認します。
5 JsonWebToken は現在の Principal を表すため、 PrincipalJsonWebToken の名前が一致することを確認します。
6 Principal の名前を取得します。
7 呼び出し元の名前、リクエスト SecurityContextisSecure() および getAuthenticationScheme() の状態、および null 以外の JsonWebToken が挿入されたかどうかを含む応答を構築します。

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

これで、次のいずれかのコマンドを使用して、アプリケーションを開発モードで実行する準備が整いました。

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

次に、以下の例のような出力が表示されるはずです。

quarkus:dev 出力
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< org.acme:security-jwt-quickstart >-----------------------
[INFO] Building security-jwt-quickstart 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
Listening for transport dt_socket at address: 5005
2020-07-15 16:09:50,883 INFO  [io.quarkus] (Quarkus Main Thread) security-jwt-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.073s. Listening on: http://0.0.0.0:8080
2020-07-15 16:09:50,885 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-07-15 16:09:50,885 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, mutiny, rest, rest-jackson, security, smallrye-context-propagation, smallrye-jwt, vertx, vertx-web]

REST エンドポイントが実行されているので、curl などのコマンドラインツールを使用してアクセスできます。

/secured/permit-allcurl コマンド
$ curl http://127.0.0.1:8080/secured/permit-all; echo

このコマンドは次の応答を返します。

hello anonymous, isHttps: false, authScheme: null, hasJWT: false

リクエストで JWT が提供されていないため、エンドポイントでセキュリティー状態が確認されることはなく、応答もそれと一致しています。

  • username は匿名です。

  • https が使用されていないため、 isHttpsfalse です。

  • authScheme はnullです

  • hasJWTfalse です。

Ctrl-Cを使用してQuarkusサーバーを停止します。

では実際に何かをセキュア化してみましょう。下記の新しいエンドポイントメソッド helloRolesAllowed を見てみましょう。

REST エンドポイント V2
package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; (1)

    @GET
    @Path("permit-all")
    @PermitAll
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx);
    }

    @GET
    @Path("roles-allowed") (2)
    @RolesAllowed({ "User", "Admin" }) (3)
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowed(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + jwt.getClaim("birthdate").toString(); (4)
    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) {
            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName();
        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
1 JWT からのクレームにアクセスするために、 JsonWebToken が挿入されます。
2 このエンドポイントは /secured/roles-allowed で公開されます。
3 @RolesAllowed アノテーションは、ユーザーまたは管理者のロールを持つユーザーへのアクセスを制限します。
4 レスポンスは hello メソッドと同様に構築されますが、挿入された JsonWebToken から直接取得された birthdate クレームが追加されます。

TokenSecuredResource にこれを追加した後、 ./mvnw quarkus:dev コマンドを再実行し、 curl -v http://127.0.0.1:8080/secured/roles-allowed; echo を実行して新しいエンドポイントへのアクセスを試みます。

出力は以下のようになるはずです:

/secured/roles-allowed の curl コマンド
$ curl -v http://127.0.0.1:8080/secured/roles-allowed; echo

このコマンドは次の応答を返します。

*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /secured/roles-allowed HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Connection: keep-alive
< Content-Type: text/html;charset=UTF-8
< Content-Length: 14
< Date: Sun, 03 Mar 2019 16:32:34 GMT
<
* Connection #0 to host 127.0.0.1 left intact

リクエストに JWT が指定されなかったため、エンドポイントへのアクセスが正しく拒否されました。 代わりに、HTTP 401 Unauthorized エラーが表示されました。

エンドポイントにアクセスするには、有効な JWT を取得してリクエストに含める必要があります。これには次の 2 つの手順が含まれます。

  1. JWT を検証するために必要な情報を含む SmallRye JWT エクステンションを設定する。

  2. 設定に一致する適切なクレームを含む JWT を生成する。

SmallRye JWT エクステンションのセキュリティー情報を設定する。

次の内容で security-jwt-quickstart/src/main/resources/application.properties を作成します。

TokenSecuredResource のアプリケーションプロパティー
mp.jwt.verify.publickey.location=publicKey.pem (1)
mp.jwt.verify.issuer=https://example.com/issuer (2)

quarkus.native.resources.includes=publicKey.pem (3)
1 クラスパス上の公開鍵ファイル publicKey.pem の場所を指定します。 このキーの追加方法は 公開鍵の追加 を参照してください。
2 発行者を https://example.com/issuer として定義します。
3 publicKey.pem ファイルがネイティブ実行可能ファイルのリソースとして含まれていることを確認します。

公開鍵の追加

JWT 仕様 では、使用できる JWT のさまざまなセキュリティーレベルが定義されています。 MicroProfile JWT RBAC 仕様では、RSA-256 署名アルゴリズムで署名された JWT が必要です。 これには、RSA 公開鍵ペアが必要になります。 REST エンドポイントサーバー側では、リクエストとともに送信された JWT を検証するために使用する RSA 公開鍵の場所を設定する必要があります。 以前に設定された mp.jwt.verify.publickey.location=publicKey.pem 設定では、公開鍵がクラスパス上で publicKey.pem として使用可能であることが想定されています。 これを実現するには、次のコンテンツを security-jwt-quickstart/src/main/resources/publicKey.pem ファイルにコピーします。

RSA 公開鍵 PEM コンテンツ
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
nQIDAQAB
-----END PUBLIC KEY-----

JWT の生成

多くの場合、JWT は Keycloak などのアイデンティティーマネージャーから取得されます。 ただし、このクイックスタートでは、 smallrye-jwt によって提供される JWT 生成 API を使用して独自の JWT を生成します。 詳細は、SmallRye JWT を使用して JWT トークンを生成する を参照してください。

次のリストからコードを取得し、 security-jwt-quickstart/src/test/java/org/acme/security/jwt/GenerateToken.java に配置します。

GenerateToken メインドライバークラス
package org.acme.security.jwt;

import java.util.Arrays;
import java.util.HashSet;

import org.eclipse.microprofile.jwt.Claims;
import io.smallrye.jwt.build.Jwt;

/**
 * A utility class to generate and print a JWT token string to stdout.
 */
public class GenerateToken {

    /**
     * Generates and prints a JWT token.
     */
    public static void main(String[] args) {
        String token = Jwt.issuer("https://example.com/issuer") (1)
                .upn("jdoe@quarkus.io") (2)
                .groups(new HashSet<>(Arrays.asList("User", "Admin"))) (3)
                .claim(Claims.birthdate.name(), "2001-07-13") (4)
                .sign();

        System.out.println(token);
        System.exit(0);
    }
}
1 JWT に iss (発行者) クレームを設定します。 トークンが有効と見なされるためには、この値がサーバー側の mp.jwt.verify.issuer 設定と一致する必要があります。
2 upn (ユーザープリンシパル名) クレームを指定します。MicroProfile JWT RBAC 仕様では、コンテナーセキュリティー API で Principal を識別するための推奨クレームとして定義されています。
3 JWT ベアラーに割り当てられたグループメンバーシップと最上位レベルのロールを提供する groups クレームを定義します。
4 birthdate クレームを追加します。 これは機密情報とみなされる可能性があるため、SmallRye JWT を使用して JWT トークンを生成する で説明されているようにクレームを暗号化することを検討してください。

このコードが機能するには、 TokenSecuredResource アプリケーションにある公開鍵に対応する RSA 秘密鍵の内容が必要であることに注意してください。 次の PEM コンテンツを取得して、 security-jwt-quickstart/src/test/resources/privateKey.pem に配置します。

RSA 秘密鍵 PEM コンテンツ
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
f3cg+fr8aou7pr9SHhJlZCU=
-----END PRIVATE KEY-----

後で、 smallrye.jwt.sign.key.location プロパティーを設定して、秘密署名鍵の場所を指定します。

OpenSSL でのキーの生成

OpenSSL コマンドラインツールを使用して公開鍵と秘密鍵のペアを生成することもできます。

キーを生成するための openssl コマンド
openssl genrsa -out rsaPrivateKey.pem 2048
openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem

秘密鍵を生成し、安全なキーの保管と転送に一般的に使用される PKCS#8 形式に変換するには、追加の手順が必要です。

変換用の `openssl`コマンド
openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem

このクイックスタートで使用されているキーペアの代わりに、生成されたキーペアを使用できます。

TokenSecuredResource エンドポイントの JSON Web Token (JWT) を生成する前に application is running であることを確認します。

次に、次のコマンドを使用して JWT を生成します。

JWT 生成の出力例
$ mvn exec:java -Dexec.mainClass=org.acme.security.jwt.GenerateToken -Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem

JWT 文字列は、 . 文字で区切られた 3 つの部分が含まれる Base64 URL エンコードされた文字列です。

  1. 署名アルゴリズムなどのトークンに関するメタデータが含まれるヘッダー。

  2. ペイロードはクレームとも呼ばれ、トークンのクレームまたはデータが含まれます。

  3. トークンの整合性を検証する署名。

/secured/roles-allowed へのセキュリティーで保護されたアクセス

ここで、これを使用して、 /secured/roles-allowed エンドポイントにセキュリティー保護されたリクエストを送信してみましょう。 Quarkus サーバーが開発モードで実行されていることを確認してから、次のコマンドを実行し、前の手順で生成された JWT のバージョンを必ず使用します。

JWT を含む /secured/roles-allowed の curl コマンド
$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo

生成されたトークンを HTTP 認可 Bearer スキームの値として必ず使用してください。

このコマンドは次の応答を返します。

hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13

正常に完了しました。これで次のようになりました。

  • 匿名でない発信者名: jdoe@quarkus.io

  • 認証スキーム: Bearer

  • null 以外の JsonWebToken

  • birthdate クレーム値

JsonWebToken とクレームインジェクションの使用

これで、セキュリティー保護された REST エンドポイントにアクセスするための JWT を生成できるようになりました。次に、 JsonWebToken インターフェイスと JWT クレームを使用して何ができるかを見てみましょう。 org.eclipse.microprofile.jwt.JsonWebToken インターフェイスは java.security.Principal インターフェイスを継承し、以前に使用した jakarta.ws.rs.core.SecurityContext#getUserPrincipal() 呼び出しによって返されるオブジェクトタイプです。 つまり、CDI を使用しくても REST コンテナー SecurityContext にアクセスできるコードは、 SecurityContext#getUserPrincipal() をキャストすることで、呼び出し元の JsonWebToken インターフェイスを取得できます。

JsonWebToken インターフェイスは、基盤となる JWT のクレームにアクセスするためのメソッドを定義します。これは、JWT に存在する可能性のある MicroProfile JWT RBAC 仕様および任意のクレームで必要な一般的クレームのアクセッサを提供します。。

すべての JWT クレームを挿入することもできます。 (JsonWebToken から取得するのではなく) TokenSecuredResource を、挿入された birthdate クレームを使用する別のエンドポイント /secured/roles-allowed-admin で継承してみましょう。

package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
@RequestScoped (1)
public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; (2)
    @Inject
    @Claim(standard = Claims.birthdate)
    String birthdate; (3)

    @GET
    @Path("permit-all")
    @PermitAll
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx);
    }

    @GET
    @Path("roles-allowed")
    @RolesAllowed({ "User", "Admin" })
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowed(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + jwt.getClaim("birthdate").toString();
    }

    @GET
    @Path("roles-allowed-admin")
    @RolesAllowed("Admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowedAdmin(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + birthdate; (4)
    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) {
            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName();
        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
1 birthdate クレームを String として挿入できるようにするには、 @RequestScoped スコープが必要です。
2 ここで JsonWebToken が挿入され、すべてのクレームと JWT 関連情報へのアクセスが提供されます。
3 birthdate クレームは String として挿入されます。これにより、 @RequestScoped スコープが必須である理由が強調されます。
4 挿入された birthdate クレームは、応答を構築するために直接使用されます。

次に、トークンを再度生成して実行します。

$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo

生成されたトークンを HTTP 認可 Bearer スキームの値として必ず使用してください。

このコマンドは次の応答を返します。

hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13

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-jwt-quickstart-1.0.0-SNAPSHOT-runner

ソリューションの探索

security-jwt-quickstart directory リポジトリには、このクイックスタートガイドで扱うすべてのバージョンが含まれており、さらに CDI API を使用して JsonWebToken トークンとそのクレームを注入し、サブリソースを示す追加のエンドポイントも含まれています。

`security-jwt-quickstart`ディレクトリーでクイックスタートソリューションを確認し、SmallRye JWT エクステンションの機能に関する情報を学習することを推奨します。

リファレンスガイド

サポートされている注入スコープ

org.eclipse.microprofile.jwt.JsonWebToken が注入される場合、 @ApplicationScoped@Singleton、および @RequestScoped の外部 Bean 注入スコープがすべてサポートされます。また、現在のトークンが示されていることを確認するために、 JsonWebToken@RequestScoped スコープが適用されます。

ただし、個々のトークンクレームが String などの単純な型として挿入される場合は、 @RequestScoped を使用する必要があります。以下はその例です。

package org.acme.security.jwt;

import jakarta.inject.Inject;
import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.Claims;

@Path("/secured")
@RequestScoped
public class TokenSecuredResource {

    @Inject
    @Claim(standard = Claims.birthdate)
    String birthdate;
}

注入された JsonWebToken を使用して個々のクレームにアクセスすることもできますが、この場合は @RequestScoped を設定する必要はありません。

詳細については、 MP JWT CDI 注入要件 を参照してください。

サポートされている公開鍵形式

公開鍵は、優先順位に従って、次のいずれかの形式でフォーマットできます。

  • Public Key Cryptography Standards #8 (PKCS#8) PEM

  • JSON Web Key (JWK)

  • JSON Web Key Set (JWKS)

  • JSON Web Key (JWK) Base64 URL エンコード

  • JSON Web Key Set (JWKS) Base64 URL エンコード

検証鍵の扱い

非対称 RSA または楕円曲線 (EC) 鍵を使用してトークンの署名を検証する必要がある場合は、 mp.jwt.verify.publickey.location プロパティーを使用してローカルまたはリモートの検証鍵を参照します。

mp.jwt.verify.publickey.algorithm を使用して検証アルゴリズムをカスタマイズします (デフォルトは RS256)。たとえば、EC 鍵を操作する場合は ES256 に設定します。

対称秘密鍵を使用してトークン署名を検証する必要がある場合は、JSON Web 鍵 (JWK) または JSON Web 鍵セット (JWK セット) 形式のいずれかを使用して、この秘密鍵を表す必要があります。以下はその例です。

{
 "keys": [
   {
     "kty":"oct",
     "kid":"secretKey",
     "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
   }
 ]
}

この秘密鍵 JWK は、 smallrye.jwt.verify.key.location でも参照する必要があります。 smallrye.jwt.verify.algorithmHS256/HS384/HS512 に設定する必要があります。

JWTParser を使用した JsonWebToken の解析と検証

JWT トークンを挿入できない場合、たとえば、サービスリクエストペイロードに埋め込まれていたり、サービスエンドポイントが別の経路でトークンを取得する場合、 JWTParser を使用できます。

import org.eclipse.microprofile.jwt.JsonWebToken;
import io.smallrye.jwt.auth.principal.JWTParser;
...
@Inject JWTParser parser;

String token = getTokenFromOidcServer();

// Parse and verify the token
JsonWebToken jwt = parser.parse(token);

また、トークンの検証方法や復号化方法をカスタマイズするためにも使用できます。 たとえば、ローカルの SecretKey を指定できます。

package org.acme.security.jwt;

import io.smallrye.jwt.auth.principal.ParseException;
import jakarta.inject.Inject;
import jakarta.ws.rs.CookieParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.jwt.JsonWebToken;
import io.smallrye.jwt.auth.principal.JWTParser;
import io.smallrye.jwt.build.Jwt;

@Path("/secured")
public class SecuredResource {
    private static final String SECRET = "AyM1SysPpbyDfgZld3umj1qzKObwVMko";

    @Inject
    JWTParser parser;

    @GET
    @Produces("text/plain")
    public Response getUserName(@CookieParam("jwt") String jwtCookie) throws ParseException {
        if (jwtCookie == null) {
            // Create a JWT token signed by using the 'HS256' algorithm
            String newJwtCookie = Jwt.upn("Alice").signWithSecret(SECRET);
            // or create a JWT token encrypted by using the 'A256KW' algorithm
            // Jwt.upn("alice").encryptWithSecret(secret);
            return Response.ok("Alice").cookie(new NewCookie("jwt", newJwtCookie)).build();
        } else {
            // All mp.jwt and smallrye.jwt properties are still effective; only the verification key is customized.
            JsonWebToken jwt = parser.verify(jwtCookie, SECRET);
            // or jwt = parser.decrypt(jwtCookie, secret);
            return Response.ok(jwt.getName()).build();
        }
    }
}

quarkus-smallrye-jwt で提供される HTTP サポートなしで JWTParser を使用する方法については、How to Add SmallRye JWT directly セクションも参照してください。

トークン復号化

アプリケーションが暗号化されたクレームまたは暗号化された内部署名付きクレームを含むトークンを受け入れる必要がある場合は、復号化キーを指すように smallrye.jwt.decrypt.key.location プロパティーを設定するだけです。

この鍵プロパティのみが設定されている場合、受信トークンには暗号化クレームのみが含まれる必要があります。 mp.jwt.verify.publickey または mp.jwt.verify.publickey.location のいずれかの検証プロパティーも設定されている場合、受信トークンには暗号化、内部署名付きトークンが含まれている必要があります。

SmallRye JWT を使用した JWT トークンの生成 を参照して、暗号化されたトークンまたは内部署名されたトークンをすばやく生成して暗号化する方法を学習します。

カスタムファクトリー

io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory は、JWT トークンを解析および検証し、 JsonWebToken プリンシパルに変換するために使用されるデフォルトの実装です。このファクトリーは、 Configuration セクションで説明されているように、 MP JWT および smallrye-jwt プロパティーに依存して、JWT トークンを検証およびカスタマイズします。

ファイアウォールによってすでに検証されているトークンの再検証をスキップするなど、カスタムファクトリーを実装する必要がある場合は、次のいずれかの方法で実装できます。

  • META-INF/services/io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory リソースを作成して、 ServiceLoader メカニズムを使用します。

  • 以下の例のように、 Alternative CDI Bean 実装を提供します。

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Alternative;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;
import io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipal;
import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
import io.smallrye.jwt.auth.principal.JWTCallerPrincipal;
import io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory;
import io.smallrye.jwt.auth.principal.ParseException;

@ApplicationScoped
@Alternative
@Priority(1)
public class TestJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory {

    @Override
    public JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException {
        try {
            // Token has already been verified; parse the token claims only
            String json = new String(Base64.getUrlDecoder().decode(token.split("\\.")[1]), StandardCharsets.UTF_8);
            return new DefaultJWTCallerPrincipal(JwtClaims.parse(json));
        } catch (InvalidJwtException ex) {
            throw new ParseException(ex.getMessage());
        }
    }
}

ブロッキング呼出

quarkus-smallrye-jwt エクステンションでは、現在リアクティブではない SmallRye JWT ライブラリを使用します。

`quarkus-smallrye-jwt`がリアクティブな Quarkus セキュリティーアーキテクチャーの一部として動作する観点からすると、SmallRye JWT 検証または復号化コードに入る IO スレッドが、以下のいずれかのケースでブロックされる可能性があります。

  • デフォルトのキーリゾルバーが、OIDCエンドポイントへのリモートコールを伴うキーを含む JsonWebKey セットを更新します

  • AWS Application Load Balancer (ALB) キーリゾルバーなどのカスタムキーリゾルバーは、現在のトークンのキー識別子ヘッダー値を使用して、AWS ALB キーエンドポイントに対してキーを解決します。

このような場合、接続が遅い場合 (たとえば、キーエンドポイントへの応答に 3 秒以上かかる場合)、現在のイベントループスレッドがブロックされる可能性があります。

ブロックされないようにするには、 quarkus.smallrye-jwt.blocking-authentication=true を設定します。

トークンの伝播

下流サービスへのベアラアクセストークンの伝播については、トークン伝播 の項を参照してください。

テスト

Wiremock

mp.jwt.verify.publickey.location を HTTPS または HTTP ベースの JsonWebKey (JWK) セットを指すように設定する場合は、OpenID Connect Bearer Token Integration testing Wiremock セクションで説明されているのと同じアプローチを使用できますが、代わりに MP JWT 設定プロパティーを使用するように application.properties のみを変更します。

# keycloak.url is set by OidcWiremockTestResource
mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus

Keycloak

Keycloak を使用していて、 mp.jwt.verify.publickey.location を HTTPS または HTTP ベースの JsonWebKey (JWK) セットを指すように設定する場合は、OpenID Connect Bearer Token Integration testing Keycloak セクションで説明されているのと同じアプローチを使用できますが、代わりに MP JWT 設定プロパティーを使用するように application.properties のみを変更します。

# keycloak.url is set by DevServices for Keycloak
mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus

Keycloakが発行したトークンは、レルムエンドポイントアドレスが iss (発行者)クレームに設定されていることに注目してください。

Quarkus アプリケーションが Docker コンテナー内で実行される場合、DevServices for Keycloak によって起動された Keycloak コンテナーとネットワークインターフェイスを共有する可能性があります。 このシナリオでは、Quarkus アプリケーションと Keycloak は内部の共有 Docker ネットワークを介して通信します。

そのような場合は、代わりに以下のような設定にしてください。

# keycloak.url is set by DevServices for Keycloak,
# Quarkus accesses it through an internal shared docker network interface.
mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs

# Issuer is set to the docker bridge localhost endpoint address represented by the `client.quarkus.oidc.auth-server-url` property
mp.jwt.verify.issuer=${client.quarkus.oidc.auth-server-url}

ローカル公開鍵

OpenID Connect Bearer Token Integration testing Local public key セクションで説明されているのと同じアプローチを使用できますが、代わりに MP JWT 設定プロパティーを使用するように application.properties のみを変更します。

mp.jwt.verify.publickey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9xnQIDAQAB
# set it to the issuer value which is used to generate the tokens
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus

# required to sign the tokens
smallrye.jwt.sign.key.location=privateKey.pem

TestSecurity アノテーション

次の依存関係を追加します。

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

次に、以下のようなテストコードを記述します。

import static org.hamcrest.Matchers.is;
import org.junit.jupiter.api.Test;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.quarkus.test.security.jwt.Claim;
import io.quarkus.test.security.jwt.JwtSecurity;
import io.restassured.RestAssured;

@QuarkusTest
@TestHTTPEndpoint(ProtectedResource.class)
public class TestSecurityAuthTest {

    @Test
    @TestSecurity(user = "userJwt", roles = "viewer")
    public void testJwt() {
        RestAssured.when().get("test-security-jwt").then()
                .body(is("userJwt:viewer"));
    }

    @Test
    @TestSecurity(user = "userJwt", roles = "viewer")
    @JwtSecurity(claims = {
            @Claim(key = "email", value = "user@gmail.com")
    })
    public void testJwtWithClaims() {
        RestAssured.when().get("test-security-jwt-claims").then()
                .body(is("userJwt:viewer:user@gmail.com"));
    }

}

ここで、 ProtectedResource クラスは次のようになります。

@Path("/web-app")
@Authenticated
public class ProtectedResource {

    @Inject
    JsonWebToken accessToken;

    @GET
    @Path("test-security-jwt")
    public String testSecurityOidc() {
        return accessToken.getName() + ":" + accessToken.getGroups().iterator().next();
    }

    @GET
    @Path("test-security-jwt-claims")
    public String testSecurityOidcUserInfoMetadata() {
        return accessToken.getName() + ":" + accessToken.getGroups().iterator().next()
                + ":" + accessToken.getClaim("email");
    }
}

@TestSecurity アノテーションは常に使用する必要があり、その user プロパティーは JsonWebToken.getName() として返され、 roles プロパティーは JsonWebToken.getGroups() として返されることに注意してください。 @JwtSecurity アノテーションはオプションであり、追加のトークン要求を設定するために使用できます。

@TestSecurity@JwtSecurity は、次のようにメタアノテーションで組み合わせることができます:

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD })
    @TestSecurity(user = "userOidc", roles = "viewer")
    @OidcSecurity(introspectionRequired = true,
        introspection = {
            @TokenIntrospection(key = "email", value = "user@gmail.com")
        }
    )
    public @interface TestSecurityMetaAnnotation {

    }

これは、同じセキュリティ設定のセットを複数のテストメソッドで使用する必要がある場合に特に便利です。

ログでエラーを確認する方法

トークンの検証または復号化エラーの詳細を確認するには、 io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator TRACE レベルのログを有効にしてください。

quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".level=TRACE
quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-level=TRACE

プロアクティブ認証

パブリックエンドポイントメソッド呼び出し時のトークン検証を省略したい場合は、 プロアクティブ認証 を無効にします。

トークンの検証が行われていない場合、挿入された JsonWebToken にパブリックメソッドを通じてアクセスできないことに注意してください。

SmallRye JWT を直接追加する方法

parse and verify JsonWebToken with JWTParser の場合、以下の状況では quarkus-smallrye-jwt の代わりに smallrye-jwt を直接使用してください。

  • HTTP をサポートしていないQuarkusエクステンション、例えば Quarkus GRPC などを使用している場合。

  • エクステンション固有の HTTP を指定し、そのサポートは quarkus-smallrye-jwt および Vert.x HTTP (Quarkus AWS Lambda など) によって提供されるサポートと競合している場合。

まず、 smallrye-jwt の依存関係を追加することから始めます:

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

さらに、 application.properties を更新して、 smallrye-jwt によって提供されるすべての CDI プロデューサーを次のように含めます。

quarkus.index-dependency.smallrye-jwt.group-id=io.smallrye
quarkus.index-dependency.smallrye-jwt.artifact-id=smallrye-jwt

設定リファレンス

Quarkus の設定

ビルド時に固定された設定プロパティー。その他の設定プロパティーは、すべて実行時にオーバーライド可能です。

Configuration property

デフォルト

The MP-JWT configuration object

Environment variable: QUARKUS_SMALLRYE_JWT_ENABLED

Show more

boolean

true

The name of the java.security.Provider that supports SHA256withRSA signatures

Environment variable: QUARKUS_SMALLRYE_JWT_RSA_SIG_PROVIDER

Show more

string

SunRsaSign

Enable this property if fetching the remote keys can be a time-consuming operation. Do not enable it if you use the local keys.

Environment variable: QUARKUS_SMALLRYE_JWT_BLOCKING_AUTHENTICATION

Show more

boolean

false

Always create HTTP 401 challenge, even for requests containing no authentication credentials. JWT authentication mechanism will return HTTP 401 when an authentication challenge is required. However if it is used alongside one of the interactive authentication mechanisms then returning HTTP 401 to the users accessing the application from a browser may not be desired. If you prefer you can request that JWT authentication mechanism does not create a challenge in such cases by setting this property to 'true'.

Environment variable: QUARKUS_SMALLRYE_JWT_SILENT

Show more

boolean

false

MicroProfile JWT の設定

プロパティ名 デフォルト 説明

mp.jwt.verify.publickey

なし

mp.jwt.verify.publickey 設定プロパティーを使用すると、公開鍵テキスト自体を文字列として提供できます。公開鍵は、サポートされている公開鍵形式 セクションで定義された順序で、提供された文字列から解析されます。

mp.jwt.verify.publickey.location

なし

Config プロパティーでは、公開鍵の外部または内部の場所を指定できます。値は、相対パスまたは URL を使用できます。値が HTTPS ベースの JWK セットを指している場合、ネイティブモードで動作させるには、 quarkus.ssl.native プロパティーも true に設定する必要があります。詳細は、ネイティブ実行可能ファイルでの SSL の使用 を参照してください。

mp.jwt.verify.publickey.algorithm

RS256

署名アルゴリズムのリスト。楕円曲線署名アルゴリズムをサポートするには、 ES256 に設定します。

mp.jwt.decrypt.key.location

なし

Config プロパティーを使用すると、秘密復号化キーの外部または内部の場所を指定できます。

mp.jwt.decrypt.key.algorithm

RSA-OAEPRSA-OAEP-256

復号化アルゴリズムのリスト。SHA-256 のみの RSA-OAEP をサポートするには、 RSA-OAEP-256 に設定します。

mp.jwt.verify.issuer

なし

Config プロパティーは、サーバーが有効として受け入れる JWT の iss (発行者) クレームの値を指定します。

mp.jwt.verify.audiences

なし

トークン aud クレームに含まれる可能性のあるオーディエンスのコンマ区切りリスト。

mp.jwt.verify.clock.skew

60

トークンの有効期限と年齢確認時に使用されるクロックスキュー(秒)。トークンの有効期限切れ後、現在時刻がこのプロパティで指定された秒数以内であれば、期限切れのトークンは受理されます。デフォルト値は60秒です。

mp.jwt.verify.token.age

none

トークン発行時刻 iat から経過してはならない秒数です。

mp.jwt.token.header

Authorization

Cookie などの別のヘッダーを使用してトークンを渡す場合は、このプロパティーを設定します。

mp.jwt.token.cookie

なし

トークンを含む Cookie の名前。このプロパティーは、 mp.jwt.token.headerCookie に設定されている場合にのみ有効です。

追加の SmallRye JWT 設定

SmallRye JWT は、トークン処理のカスタマイズに使用できるプロパティーを他にも提供します。

プロパティ名 デフォルト 説明

smallrye.jwt.verify.secretkey

なし

秘密鍵は文字列として提供されます。

smallrye.jwt.verify.key.location

NONE

公開鍵と秘密鍵の両方を指すことができる検証鍵の場所。秘密鍵は JWK 形式でのみ使用できます。このプロパティーが設定されている場合、'mp.jwt.verify.publickey.location' は無視されることに注意してください。

smallrye.jwt.verify.algorithm

署名アルゴリズム。このプロパティーは、 HS256 などの対称アルゴリズムを設定する場合にのみ使用してください。 ES256 などの非対称アルゴリズムの設定には非推奨です。代わりに 'mp.jwt.verify.publickey.algorithm' を使用してください。

smallrye.jwt.verify.key-format

ANY

このプロパティーを PEM_KEYPEM_CERTIFICATEJWKJWK_BASE64URL などの特定のキー鍵形式に設定して、検証鍵のロード方法を最適化します。

smallrye.jwt.verify.key-provider

DEFAULT

デフォルトでは、PEM、JWK、または JWK キーセットは、MicroProfile JWT 仕様で要求されているように、ローカルファイルシステムから読み取ったり、URI から取得したりできます。AWS Application Load Balancer 検証キー解決をサポートするには、このプロパティーを AWS_ALB に設定します。

smallrye.jwt.verify.relax-key-validation

false

検証キーの検証を緩和します。このプロパティーを true に設定すると、長さが 2048 ビット未満である公開 RSA 鍵が許可されます。

smallrye.jwt.verify.certificate-thumbprint

false

このプロパティーが有効になっている場合、署名されたトークンには、x5t または x5t#S256X509Certificate サムプリントヘッダーが含まれている必要があります。検証鍵は、JWK または PEM 証明書鍵形式でのみ使用できます。JWK 鍵には、x5c (Base64 でエンコードされた X509Certificate) プロパティーセットが必要です。

smallrye.jwt.token.header

Authorization

Cookie などの別のヘッダーを使用してトークンを渡す場合は、このプロパティーを設定します。このプロパティーは推奨されていません。'mp.jwt.token.header' を使用してください。

smallrye.jwt.key-cache-size

100

キーキャッシュのサイズ。このプロパティは、 smallrye.jwt.key-cache-time-to-live と同様に、 AWS_ALB のようなキープロバイダーが、鍵を動的に解決するために smallrye.jwt.verify.key-provider=AWS_ALB で構成されている場合に、キーキャッシュを制御するために使用します。

smallrye.jwt.key-cache-time-to-live

10

キーキャッシュエントリーの有効期間 (分単位)。 AWS_ALB などのキープロバイダーが smallrye.jwt.verify.key-provider=AWS_ALB で設定され、キーが動的に解決される場合、このプロパティーと smallrye.jwt.key-cache-size を使用してキーキャッシュを制御します。

smallrye.jwt.token.cookie

なし

トークンを含むクッキーの名前。このプロパティ=は、 smallrye.jwt.token.headerCookie に設定されている場合にのみ有効です。 このプロパティーは非推奨です。 mp.jwt.token.cookie を使用してください。

smallrye.jwt.always-check-authorization

false

smallrye.jwt.token.headerCookie に設定されていても、名前が smallrye.jwt.token.cookie の Cookie が存在しない場合、 Authorization ヘッダーがチェックされるようにこのプロパティーを true に設定します。

smallrye.jwt.token.schemes

Bearer

DPoP などの単一または複数の代替スキームを含むコンマ区切りのリスト。

smallrye.jwt.token.kid

なし

鍵の識別子。検証 JWK キーとすべての JWT トークンには、設定されている場合は一致する kid ヘッダーが必要です。

smallrye.jwt.time-to-live

なし

JWT を発行して使用できる最大秒数。実質的に、JWT の有効期限と発行日の差はこの値を超えてはなりません。このプロパティーを正以外の値に設定すると、トークンに有効な iat (発行日) クレームが必要であるという要件が緩和されます。

smallrye.jwt.require.named-principal

true

アプリケーションが名前を返す java.security.Principal に依存している場合、トークンには upn または preferred_username または sub クレームセットが必要です。このプロパティーを設定すると、アプリケーションコードが null 以外の Principal 名を確実に処理するためにこれらのクレームがいずれも利用できない場合、SmallRye JWT は例外を出力します。

smallrye.jwt.path.sub

なし

件名を含むクレームへのパス。これは最上位の JSON オブジェクトから始まり、各セグメントが JSON オブジェクト名のみを表す複数のセグメントを含めることができます (例: レルム s/subject)。このプロパティーは、トークンに 'sub' クレームがなく、サブジェクトが別のクレームに設定されている場合に使用できます。名前空間修飾クレームには二重引用符を使用します。

smallrye.jwt.claims.sub

なし

現在のトークンに使用可能な標準またはカスタムの sub クレームがない場合に、このプロパティーを使用して、デフォルトのサブクレーム値を設定できます。事実上、このプロパティーを使用して、 upnpreferred_usernamesub`クレームが設定されていない場合に `java.security.Principal 名をカスタマイズできます。

smallrye.jwt.path.groups

なし

グループを含むクレームへのパス。これは最上位の JSON オブジェクトから始まり、各セグメントが JSON オブジェクト名のみを表す複数のセグメントを含めることができます (例: レルム/groups)。このプロパティーは、トークンに 'groups' クレームがなく、別のクレームにグループが設定されている場合に使用できます。名前空間修飾クレームには二重引用符を使用します。

smallrye.jwt.groups-separator

space

複数のグループ値を含む可能性のある文字列を分割するためのセパレーター。これは、 smallrye.jwt.path.groups プロパティーが値が文字列のカスタムクレームを指している場合にのみ使用されます。標準の OAuth2 scope クレームにはスペースで区切られたシーケンスが含まれている可能性があるため、デフォルト値はスペース 1 個です。

smallrye.jwt.claims.groups

なし

このプロパティーでは、現在のトークンに使用可能な標準またはカスタムのグループクレームがない場合に、デフォルトのグループクレーム値を設定できます。

smallrye.jwt.jwks.refresh-interval

60

JWK キャッシュの更新間隔 (分単位)。 mp.jwt.verify.publickey.location が HTTP または HTTPS URL ベースの JWK セットを指し、正の max-age パラメーター値を持つ HTTP Cache-Control レスポンスヘッダーが JWK HTTPS エンドポイントから返されない限り無視されます。

smallrye.jwt.jwks.forced-refresh-interval

30

強制 JWK キャッシュ更新間隔 (分単位)。現在のトークンの kid ヘッダーと一致する kid プロパティーを持つ JWK キーがキャッシュにないためにトークンの検証が失敗した場合に発生する可能性がある強制更新の試行頻度を制限するために使用されます。 mp.jwt.verify.publickey.location が HTTP または HTTPS URL ベースの JWK セットを指していない限り、無視されます。

smallrye.jwt.expiration.grace

0

有効期限を秒単位で指定します。デフォルトでは、現在時刻がトークンの有効期限から 1 分以内であれば、期限切れのトークンはまだ受け入れられます。このプロパティーは非推奨です。代わりに mp.jwt.verify.clock.skew を使用してください。

smallrye.jwt.verify.aud

なし

トークン aud クレームに含まれる可能性のあるオーディエンスのコンマ区切りリスト。このプロパティーは非推奨です。 mp.jwt.verify.audiences を使用してください。

smallrye.jwt.required.claims

なし

トークンに含める必要があるクレームのコンマ区切りリスト。

smallrye.jwt.decrypt.key.location

なし

秘密復号鍵の外部または内部の場所を指定するための設定プロパティー。このプロパティーは非推奨です。 mp.jwt.decrypt.key.location を使用してください。

smallrye.jwt.decrypt.algorithm

RSA_OAEP

復号化アルゴリズム。

smallrye.jwt.decrypt.key

なし

文字列として提供される復号化キー。

smallrye.jwt.token.decryption.kid

なし

復号化キー識別子。設定されている場合、復号化 JWK キーとすべての JWT トークンには、一致する kid ヘッダーが必要です。

smallrye.jwt.client.tls.certificate.path

なし

鍵を HTTPS 経由で取得する必要がある場合に設定する必要がある可能性のある TLS 信頼済み証明書へのパス。

smallrye.jwt.client.tls.trust-all

false

すべてのホスト名を信頼します。キーを HTTPS 経由でフェッチする必要があり、このプロパティーが true に設定されている場合、デフォルトですべてのホスト名が信頼されます。

smallrye.jwt.client.tls.hosts

なし

信頼できるホスト名のセット。キーを HTTPS 経由でフェッチする必要があり、 smallrye.jwt.client.tls.trust-allfalse に設定されている場合、このプロパティーを使用して信頼できるホスト名を設定できます。

smallrye.jwt.http.proxy.host

なし

HTTP プロキシーホスト。

smallrye.jwt.http.proxy.port

80

HTTP プロキシーポート。

smallrye.jwt.keystore.type

JKS

このプロパティーは、 mp.jwt.verify.publickey.location または mp.jwt.decrypt.key.location のいずれかが KeyStore ファイルを指している場合に、キーストアタイプをカスタマイズするために使用できます。設定されていない場合は、ファイル名のチェックおよびキーストアタイプの決定が行われ、デフォルトで JKS に設定されます。

smallrye.jwt.keystore.provider

mp.jwt.verify.publickey.location または mp.jwt.decrypt.key.locationKeyStore ファイルを指している場合、このプロパティーを使用して KeyStore プロバイダーをカスタマイズできます。

smallrye.jwt.keystore.password

キーストアのパスワード。 mp.jwt.verify.publickey.location または mp.jwt.decrypt.key.location の場合は、このプロパティーを設定する必要があります。

smallrye.jwt.keystore.verify.key.alias

このプロパティーは、 mp.jwt.verify.publickey.location`が `KeyStore`ファイルを指している場合に、 `KeyStore から抽出される公開検証鍵を一致する証明書から識別するために設定する必要があります。

smallrye.jwt.keystore.decrypt.key.alias

このプロパティは、 mp.jwt.decrypt.key.locationKeyStore ファイルを指している場合、プライベートな復号鍵を特定するために設定する必要があります。

smallrye.jwt.keystore.decrypt.key.password

このプロパティーは、 mp.jwt.decrypt.key.locationKeyStore ファイルを指しているときに、 KeyStore 内の秘密復号化鍵のパスワードが smallrye.jwt.keystore.password と異なる場合に設定できます。

smallrye.jwt.resolve-remote-keys-at-startup

false

アプリケーションの起動時にリモート鍵を解決するには、このプロパティーを true に設定します。

関連コンテンツ