1.3. リファレンスガイド


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

@ApplicationScoped@Singleton、および @RequestScoped outer Bean インジェクションスコープは、org.eclipse.microprofile.jwt.JsonWebToken を注入するとすべてサポートされ、現在のトークンが表されるように 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;
}
Copy to Clipboard Toggle word wrap

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

詳細は、MP JWT CDI Injection Requirements を参照してください。

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

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

  • 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 エンコード)

1.3.3. 検証鍵の扱い

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

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

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

{
 "keys": [
   {
     "kty":"oct",
     "kid":"secretKey",
     "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
   }
 ]
}
Copy to Clipboard Toggle word wrap

このシークレットキー JWK は、smallrye.jwt.verify.key.location でも参照する必要があります。smallrye.jwt.verify.algorithm は、HS256/HS384/HS512 に設定する必要があります。

1.3.4. 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);
Copy to Clipboard Toggle word wrap

また、これを使用して、トークンの検証または復号化の方法をカスタマイズすることもできます。たとえば、ローカルの 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();
        }
    }
}
Copy to Clipboard Toggle word wrap

quarkus-smallrye-jwt が提供する HTTP サポートなしで JWTParser を使用する方法に関する SmallRye JWT を直接追加する方法 のセクションを参照してください。

1.3.5. トークン復号化

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

これが唯一のキープロパティーセットである場合、受信トークンには暗号化されたクレームのみが含まれることが予想されます。mp.jwt.verify.publickey または mp.jwt.verify.publickey.location 検証プロパティーのいずれかも設定されている場合、受信トークンには暗号化された内部署名トークンが含まれることが想定されます。

SmallRye JWT を使用した JWT トークンの生成 を参照し、暗号化トークンや内部署名後に暗号化されたトークンを迅速に生成する方法を確認します。

1.3.6. カスタムファクトリー

io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory は、JWT トークンを解析および検証し、JsonWebToken プリンシパルに変換するために使用されるデフォルトの実装です。このファクトリーは、Configuration セクションで説明されているように、MP JWTsmallrye-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());
        }
    }
}
Copy to Clipboard Toggle word wrap

1.3.7. 呼び出しのブロック

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 を設定します。

1.3.8. トークンの伝播

ダウンストリームサービスへの Bearer アクセストークンの伝播は、トークン伝播 セクションを参照してください。

1.3.9. テスト

1.3.9.1. Wiremock

mp.jwt.verify.publickey.location を HTTPS または HTTP ベースの JsonWebKey (JWK) セットを指すように設定した場合は、OpenID Connect Bearer Token インテグレーションテスト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
Copy to Clipboard Toggle word wrap

1.3.9.2. Keycloak

Keycloak を使用し、mp.jwt.verify.publickey.location を HTTPS または HTTP ベースの JsonWebKey (JWK) セットを指すように設定した場合は、OpenID Connect Bearer Token インテグレーションテスト の 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
Copy to Clipboard Toggle word wrap

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

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}
Copy to Clipboard Toggle word wrap

1.3.9.3. ローカル公開鍵

OpenID Connect Bearer Token インテグレーションテスト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
Copy to Clipboard Toggle word wrap

1.3.9.4. TestSecurity アノテーション

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

  • Maven を使用する場合:

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-test-security-jwt</artifactId>
        <scope>test</scope>
    </dependency>
    Copy to Clipboard Toggle word wrap
  • Gradle を使用する場合:

    testImplementation("io.quarkus:quarkus-test-security-jwt")
    Copy to Clipboard Toggle word wrap

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

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"));
    }

}
Copy to Clipboard Toggle word wrap

ここで、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");
    }
}
Copy to Clipboard Toggle word wrap

@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 {

    }
Copy to Clipboard Toggle word wrap

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

1.3.10. ログ内のエラーを確認する方法

トークンの検証または復号化エラーの詳細は、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
Copy to Clipboard Toggle word wrap

1.3.11. プロアクティブ認証

パブリックエンドポイントメソッドが呼び出されたときにトークンの検証をスキップする場合は、プロアクティブ認証 を無効にします。

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

1.3.12. SmallRye JWT を直接追加する方法

JWTParser で JsonWebToken を解析および検証 するには、以下の状況で quarkus-smallrye-jwt の代わりに smallrye-jwt を直接使用します。

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

smallrye-jwt 依存関係の追加から開始します。

  • Maven を使用する場合:

    <dependency>
        <groupId>io.smallrye</groupId>
        <artifactId>smallrye-jwt</artifactId>
    </dependency>
    Copy to Clipboard Toggle word wrap
  • Gradle を使用する場合:

    implementation("io.smallrye:smallrye-jwt")
    Copy to Clipboard Toggle word wrap

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

quarkus.index-dependency.smallrye-jwt.group-id=io.smallrye
quarkus.index-dependency.smallrye-jwt.artifact-id=smallrye-jwt
Copy to Clipboard Toggle word wrap
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2026 Red Hat
トップに戻る