JWT RBAC の使用
このガイドでは、SmallRye JWT を Quarkus アプリケーションに統合し、MicroProfile JWT 仕様に準拠した JSON Web Token (JWT) セキュリティーを実装する方法を説明します。JWT の検証方法、MicroProfile JWT の org.eclipse.microprofile.jwt.JsonWebToken としての表現、およびベアラー認証と ロールベースアクセス制御 を使用して Quarkus の HTTP エンドポイントを保護する方法を学びます。
|
Quarkus の OpenID Connect ( Quarkus アプリケーションで OIDC 認可コードフローを使用してユーザーを認証する必要がある場合は、OpenID Connect エクステンションを使用する必要があります。詳細については、Web アプリケーションを保護するための OIDC コードフローメカニズム を参照してください。 |
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOMEが適切に設定されていること -
Apache Maven 3.9.15
-
使用したい場合は、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
クイックスタート
ソリューション
アプリケーションを段階的に作成するには、次のセクションの指示に従うことを推奨します。必要に応じて、完成した例に進むこともできます。
例にアクセスするには、Git リポジトリーをクローンするか、アーカイブをダウンロードします。
-
リポジトリーをクローンします:
git clone https://github.com/quarkusio/quarkus-quickstarts.git。 -
アーカイブ をダウンロードします。
ソリューションは security-jwt-quickstart ディレクトリー にあります。
Maven プロジェクトの作成
まず、以下のコマンドで新規プロジェクトを作成します。
Windowsユーザーの場合:
-
cmdを使用する場合、(バックスラッシュ
\を使用せず、すべてを同じ行に書かないでください)。 -
Powershellを使用する場合は、
-Dパラメータを二重引用符で囲んでください。例:"-DprojectArtifactId=security-jwt-quickstart"
このコマンドは Maven プロジェクトを生成し、MicroProfile JWT RBAC サポートを含む smallrye-jwt エクステンションをインポートします。
すでに Quarkus プロジェクトが設定されている場合は、プロジェクトのベースディレクトリーで以下のコマンドを実行することで、プロジェクトに smallrye-jwt エクステンションを追加することができます。
quarkus extension add smallrye-jwt,smallrye-jwt-build
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'
このコマンドは、ビルドファイルに以下の依存関係を追加します。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt-build</artifactId>
</dependency>
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 に以下の内容で作成します。
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 を表すため、 Principal と JsonWebToken の名前が一致することを確認します。 |
| 6 | Principal の名前を取得します。 |
| 7 | 呼び出し元の名前、リクエスト SecurityContext の isSecure() および getAuthenticationScheme() の状態、そして null 以外の JsonWebToken が挿入されたかどうかを含む応答を構築します。 |
アプリケーションを開発モードで実行する
これで、次のいずれかのコマンドを使用して、アプリケーションを開発モードで実行する準備が整いました。
quarkus dev
./mvnw quarkus:dev
./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-all に対する curl コマンド$ curl http://127.0.0.1:8080/secured/permit-all; echo
このコマンドは次の応答を返します。
hello anonymous, isHttps: false, authScheme: null, hasJWT: false
リクエストで JWT が提供されていないため、エンドポイントでセキュリティー状態が確認されることはなく、応答もそれと一致しています。
-
usernameは匿名です。 -
httpsが使用されていないため、isHttpsはfalseです。 -
authSchemeはnullです。 -
hasJWTはfalseです。
Ctrl-C を使用して Quarkus サーバーを停止します。
では実際に何かをセキュア化してみましょう。下記の新しいエンドポイントメソッド helloRolesAllowed を見てみましょう。
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 アノテーションは、"User" または "Admin" ロールを持つユーザーへのアクセスを制限します。 |
| 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 つの手順が含まれます。
-
JWT を検証するために必要な情報で SmallRye JWT エクステンションを設定します。
-
設定に一致する適切なクレームを含む 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 ファイルにコピーします。
-----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 に配置します。
-----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 コマンド
秘密鍵を生成し、安全なキーの保管と転送に一般的に使用される PKCS#8 形式に変換するには、追加の手順が必要です。 変換を実行するための
openssl コマンド
このクイックスタートで使用されているキーペアの代わりに、生成されたキーペアを使用できます。 |
TokenSecuredResource エンドポイントの JSON Web Token (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 エンコードされた文字列です。
-
署名アルゴリズムなど、トークンに関するメタデータを含むヘッダー。
-
ペイロード (「クレーム」とも呼ばれます) には、トークンのクレームまたはデータが含まれます。
-
トークンの整合性を検証する署名。
最後に、/secured/roles-allowed へのセキュリティーで保護されたアクセス
ここで、これを使用して、 /secured/roles-allowed エンドポイントにセキュリティー保護されたリクエストを送信してみましょう。
Quarkus サーバーが開発モードでまだ実行されていることを確認してから、次のコマンドを実行し、前の手順で生成された 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 のクレームにアクセスするためのメソッドを定義します。これは、MicroProfile JWT RBAC 仕様で必須とされる共通のクレーム、および JWT に存在する可能性のある任意のクレームのアクセッサを提供します。
すべての JWT クレームを注入することもできます。
(JsonWebToken から取得するのではなく) 注入された birthdate クレームを使用する別のエンドポイント /secured/roles-allowed-admin で TokenSecuredResource を拡張してみましょう。
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 アプリケーションとして実行できます。
-
アプリケーションをコンパイルします。
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-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 Injection Requirements を参照してください。
サポートされている公開鍵形式
公開鍵は、以下のいずれかの形式でフォーマットできます。優先順位順に示します。
-
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 Key (JWK) または JSON Web Key Set (JWK Set) 形式のいずれかを使用する必要があります。例:
{
"keys": [
{
"kty":"oct",
"kid":"secretKey",
"k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}
]
}
この秘密鍵 JWK は、 smallrye.jwt.verify.key.location でも参照する必要があります。
smallrye.jwt.verify.algorithm は HS256/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メカニズムを使用します。 -
以下の例のように、
AlternativeCDI 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 スレッドが、以下のいずれかのケースでブロックされる可能性があります。
-
デフォルトのキーリゾルバーは、キーを含む
JsonWebKeyセットを更新します。これには OIDC エンドポイントへのリモート呼び出しが含まれます。 -
AWS Application Load Balancer(ALB) キーリゾルバーなどのカスタムキーリゾルバーは、現在のトークンのキー識別子ヘッダー値を使用して、AWS ALB キーエンドポイントに対してキーを解決します。
このような場合、接続が遅い場合 (たとえば、キーエンドポイントへの応答に 3 秒以上かかる場合)、現在のイベントループスレッドがブロックされる可能性があります。
ブロックされないようにするには、 quarkus.smallrye-jwt.blocking-authentication=true を設定します。
トークンの伝播
下流サービスへのベアラーアクセストークンの伝播については、トークン伝播 の項を参照してください。
テスト
自動鍵生成
このエクステンションは、検証キーが設定されていない場合、開発モードとテストモードで非対称 RSA 2024 ビット署名キーペアを生成します。キーペアが生成されると、公開 RSA キーは mp.jwt.verify.publickey プロパティーを設定するために使用され、RSA 秘密キーは smallrye-jwt-build を使用してトークンに署名するためにテストで利用可能になります。例えば次のとおりです。
import io.smallrye.jwt.build.Jwt;
import jakarta.ws.rs.GET;
@GET
public String token() {
return Jwt.upn("Alice").sign();
}
詳細については、クレーム署名ガイド を参照してください。
以下のプロパティーの少なくとも 1 つを設定することで、自動キー生成を無効にできます。
-
mp.jwt.verify.publickey.location -
mp.jwt.verify.publickey -
mp.jwt.decrypt.key.location -
smallrye.jwt.encrypt.key.location -
smallrye.jwt.sign.key.location -
smallrye.jwt.sign.key
|
開発モード では、 発行者をプログラムで設定したい場合は、デフォルト値が適用されないように |
Wiremock
mp.jwt.verify.publickey.location を HTTPS または HTTP ベースの JsonWebKey (JWK) セットを指すように設定する場合は、OpenID Connect Bearer Token Integration testing の Wiremock セクションで説明されているのと同じアプローチを使用できますが、 application.properties を変更して MP JWT 設定プロパティーを使用するだけです。
# 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 セクションで説明されているのと同じアプローチを使用できますが、 application.properties を変更して MP JWT 設定プロパティーを使用するだけです。
# 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 セクションで説明されているのと同じアプローチを使用できますが、 application.properties を変更して MP JWT 設定プロパティーを使用するだけです。
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 アノテーション
次の依存関係を追加します。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-security-jwt</artifactId>
<scope>test</scope>
</dependency>
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 アノテーションはオプションであり、追加のトークンクレームを設定するために使用できます。
|
これは、同じセキュリティー設定のセットを複数のテストメソッドで使用する必要がある場合に特に便利です。 |
ログでエラーを確認する方法
トークンの検証または復号化エラーの詳細を確認するには、 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 を直接追加する方法
JWTParser を使用して JsonWebToken を解析および検証する には、以下の状況では quarkus-smallrye-jwt の代わりに smallrye-jwt を直接使用してください。
-
Quarkus GRPCのように、HTTPをサポートしない Quarkus エクステンションを使用している場合。 -
Quarkus AWS Lambdaのように、quarkus-smallrye-jwtやVert.x HTTPが提供するサポートと競合する、エクステンション固有のHTTPサポートを提供している場合。
まず、 smallrye-jwt の依存関係を追加することから始めます。
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-jwt</artifactId>
</dependency>
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: Show more |
boolean |
|
The name of the Environment variable: Show more |
string |
|
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: Show more |
boolean |
|
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: Show more |
boolean |
|
JWT authentication mechanism priority. Environment variable: Show more |
int |
|
MicroProfile JWT の設定
| プロパティ名 | デフォルト | 説明 |
|---|---|---|
|
|
|
|
|
設定プロパティーでは、公開鍵の外部または内部の場所を指定できます。値は、相対パスまたは URL を使用できます。値が HTTPS ベースの JWK セットを指している場合、ネイティブモードで動作させるには、 |
|
|
署名アルゴリズムのリスト。楕円曲線署名アルゴリズムをサポートするには、 |
|
|
設定プロパティーを使用すると、秘密復号化キーの外部または内部の場所を指定できます。 |
|
|
復号アルゴリズムのリスト。 |
|
|
設定プロパティーは、サーバーが有効として受け入れる JWT の |
|
|
トークン |
|
|
トークンの有効期限と年齢確認時に使用されるクロックスキュー(秒)。トークンの有効期限切れ後、現在時刻がこのプロパティーで指定された秒数以内であれば、期限切れのトークンは受理されます。デフォルト値は 60 秒です。 |
|
|
トークン |
|
|
|
|
|
トークンを含む Cookie の名前。このプロパティーは、 |
追加の SmallRye JWT 設定
SmallRye JWT は、トークン処理のカスタマイズに使用できるプロパティーを他にも提供します。
| プロパティ名 | デフォルト | 説明 |
|---|---|---|
|
|
秘密鍵は文字列として提供されます。 |
|
|
公開鍵と秘密鍵の両方を指すことができる検証鍵の場所。秘密鍵は JWK 形式でのみ使用できます。このプロパティーが設定されている場合、'mp.jwt.verify.publickey.location' は無視されることに注意してください。 |
|
署名アルゴリズム。このプロパティーは、 |
|
|
|
このプロパティーを |
|
|
デフォルトでは、PEM、JWK、または JWK キーセットは、MicroProfile JWT 仕様で要求されているように、ローカルファイルシステムから読み取ったり、URI から取得したりできます。このプロパティーを |
|
|
検証キーの検証を緩和します。このプロパティーを |
|
|
このプロパティーが有効になっている場合、署名されたトークンには「x5t」または「x5t#S256」X509Certificate サムプリントヘッダーが含まれている必要があります。検証キーは JWK または PEM 証明書鍵形式のみ使用できます。JWK キーには「x5c」(Base64 でエンコードされた X509Certificate) プロパティーが設定されている必要があります。 |
|
|
|
|
|
キーキャッシュのサイズ。 |
|
|
キーキャッシュエントリーの有効期間 (分単位)。 |
|
|
トークンを含む Cookie の名前。このプロパティーは、 |
|
|
|
|
|
|
|
|
鍵の識別子。設定されている場合、検証 JWK キーとすべての JWT トークンには、一致する |
|
|
JWT を発行して使用できる最大秒数。実質的に、JWT の有効期限と発行日の差がこの値を超えてはなりません。このプロパティーを正でない値に設定すると、トークンが有効な「iat」(発行日) クレームを持つという要件が緩和されます。 |
|
|
アプリケーションが |
|
|
件名を含むクレームへのパス。これは最上位の JSON オブジェクトから始まり、各セグメントが JSON オブジェクト名のみを表す複数のセグメントを含めることができます (例: |
|
|
現在のトークンに使用可能な標準またはカスタムの |
|
|
グループを含むクレームへのパス。これは最上位の JSON オブジェクトから始まり、各セグメントが JSON オブジェクト名のみを表す複数のセグメントを含めることができます (例: |
|
|
複数のグループ値を含む可能性のある文字列を分割するためのセパレーター。これは、 |
|
|
現在のトークンに使用可能な標準またはカスタムのグループクレームがない場合に、このプロパティーを使用してデフォルトのグループクレーム値を設定できます。 |
|
|
JWK キャッシュの更新間隔 (分単位)。 |
|
|
強制 JWK キャッシュ更新間隔 (分単位)。これは、キャッシュに現在のトークンの |
|
|
有効期限を秒単位で指定します。デフォルトでは、現在時刻がトークンの有効期限から 1 分以内であれば、期限切れのトークンはまだ受け入れられます。このプロパティーは非推奨です。代わりに |
|
|
トークン |
|
|
トークンに含める必要があるクレームのコンマ区切りリスト。 |
|
|
秘密復号鍵の外部または内部の場所を指定するための設定プロパティー。このプロパティーは非推奨です。 |
|
|
復号化アルゴリズム。 |
|
|
文字列として提供される復号化キー。 |
|
|
復号化キー識別子。設定されている場合、復号化 JWK キーとすべての JWT トークンには、一致する |
|
|
鍵を |
|
|
すべてのホスト名を信頼します。キーを |
|
|
信頼できるホスト名のセット。キーを |
|
|
HTTP プロキシーホスト。 |
|
|
HTTP プロキシーポート。 |
|
|
このプロパティーは、 |
|
|
|
|
キーストアのパスワード。 |
|
|
このプロパティーは、 |
|
|
このプロパティは、 |
|
|
このプロパティーは、 |
|
|
|
アプリケーションの起動時にリモート鍵を解決するには、このプロパティーを true に設定します。 |