The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

セキュリティーアーキテクチャとガイド

Quarkus Securityでは、開発者がQuarkusアプリケーションの商用品質のセキュリティーを構築するためのアーキテクチャ、複数の認証および認可メカニズム、その他のツールを提供しています。

このドキュメントでは、Quarkus Securityの簡単な概要と、各ガイドへのリンクについて説明しています。

はじめに

Please see the Getting Started With Security guide for a quick walkthrough through Quarkus Security where you can learn how to use Basic HTTP Authentication mechanism and JPA Identity Provider to create SecurityIdentity and authorize a secure access to the endpoint with Role Based Access Control.

アーキテクチャ

HttpAuthenticationMechanism は、Quarkus HTTP Securityのメインエントリーです。

Quarkus Security Managerは、 HttpAuthenticationMechanism を使用してHTTPリクエストから認証資格情報を抽出し、 IdentityProvider に委任して、これらの認証情報の SecurityIdentity への変換を完了させます。

例えば、資格情報は、HTTP Authorization ヘッダー、クライアントの HTTPS 証明書、またはクッキーを使用している場合があります。

IdentityProvider は認証資格情報を検証し、ユーザー名、ロール、元の認証資格情報、およびその他の属性を含む SecurityIdentity にマップします。

認証済みリソースごとに、 SecurityIdentity インスタンスを注入して、認証済みの ID 情報を取得することができます。

他の文脈では、JAX-RSであれば SecurityContext 、JWTであれば JsonWebToken のように、同じ情報(またはその一部)を他の別の表現で表現している場合があります。

認証メカニズム

Quarkusは、認証情報をロードするためのいくつかのソースをサポートしています。

基本認証とフォーム認証の仕組み

Basic HTTPベースの認証メカニズムとForm HTTPベースの認証メカニズムは、Quarkusでサポートされている主要な認証メカニズムです。詳細は、Basic HTTP Authentication および Form HTTP Authentication を参照してください。

WebAuthn 認証メカニズム

WebAuthn は、パスワードを置き換えるために設計された認証メカニズムです。つまり、新しいユーザーを登録したり、ログインしたりするサービスを書くたびに、パスワードを要求する代わりに、WebAuthn を使って、パスワードを置き換えるのです。

詳細については、個別のWebAuthn ドキュメント を参照してください。

相互TLS認証

Quarkusは相互TLS認証を提供しているので、X.509証明書に基づいてユーザーを認証できます。

詳しくは 相互TLS認証 をご覧ください。

OpenID Connect

quarkus-oidc エクステンションは、Bearer Token および Authorization Code Flow 認証メカニズムをサポートする、リアクティブで相互運用可能なマルチテナント対応の OpenID Connect アダプターを提供します。

Bearer Token メカニズムは、HTTP Authorization ヘッダーからトークンを抽出します。Authorization Code Flow メカニズムは、OpenId Connect Authorization Code Flow を使用します。これは、ユーザーを IDP にリダイレクトして認証を行い、提供されたコードグラントを ID、アクセストークン、リフレッシュトークンと交換することで、ユーザーが Quarkus にリダイレクトされた後に認証プロセスを完了させます。

ID とアクセス JWT トークンは、リフレッシュ可能な JWK キーセットで検証されますが、JWT と不透明な (バイナリーの) トークンの両方をリモートで検証することができます。

Bearer Token 認証メカニズムの詳細については、Using OpenID Connect to Protect Service Applications ガイドを参照してください。

Authorization Code Flow 認証メカニズムの詳細については、Using OpenID Connect to Protect Web Application ガイドを参照してください。

quarkus-oidc BearerAuthorization Code Flow の両方の認証メカニズムは、SmallRye JWT を使用して Microprofile JWT org.eclipse.microprofile.jwt.JsonWebToken として JWT トークンを表します。

Bearer または Authorization Code Flow 認証メカニズムをサポートし、静的または動的に設定できる複数のテナントの詳細については、Using OpenID Connect Multi-Tenancy を参照してください。

If you prefer to have Quarkus OIDC extension enabled at runtime then set quarkus.oidc.tenant-enabled=false at build time and re-enable it at runtime using a system property. See also Disabling Tenant Configurations for more information about managing the individual tenant configurations in the multi-tenant OIDC deployments.

Keycloak と Bearer トークンを使用する場合は、Using Keycloak to Centralize Authorization ガイドも参照してください。

プログラムで Keycloak を設定する必要がある場合は、quarkus-keycloak-admin-client または quarkus-keycloak-admin-client-reactive (アプリケーションが quarkus-rest-client-reactive を使用する場合) エクステンションを使用して、https://www.keycloak.org/docs/latest/server_development/#admin-rest-api[Keycloak Admin REST API] を使用することを検討してください。

OpenID Connect クライアントとフィルター

quarkus-oidc-client エクステンションは、client-credentialspassword および refresh_token トークングラントをサポートする OpenID Connect および OAuth2 プロバイダーからアクセストークンを取得したり、更新したりするための OidcClient を提供します。

quarkus-oidc-client-filter エクステンションは quarkus-oidc-client エクステンションに依存し、OidcClient で取得したアクセストークンを HTTP Authorization ヘッダーの Bearer スキーム値として設定する JAX-RS OidcClientRequestFilter を提供します。このフィルターは、現在の Quarkus エンドポイントに注入されたMP RestClient 実装で登録することができますが、このサービスエンドポイントの認証要件には関係ありません。たとえば、パブリックエンドポイントにすることもできますし、MTLSで保護することもできます。重要な点は、この Quarkus エンドポイント自体を、Quarkus OpenID Connect アダプターで保護する必要がないことです。

quarkus-oidc-token-propagation エクステンションは quarkus-oidc エクステンションに依存し、OpenID Connect Bearer または Authorization Code Flow アクセストークンを HTTP Authorization ヘッダーの Bearer スキーム値として設定する JAX-RS TokenCredentialRequestFilter を提供します。このフィルターは、現在の Quarkus エンドポイントに注入された MP RestClient 実装で登録することができ、Quarkus エンドポイント自体は Quarkus OpenID Connect アダプターで保護する必要があります。このフィルターは、アクセストークンをダウンストリームサービスに伝播させるために使用できます。

詳細は、OpenID Connect and Token Propagation Quickstart ガイドおよび OpenID Connect and OAuth2 Client Reference ガイドを参照してください。

SmallRye JWT

quarkus-smallrye-jwt はMicroprofile JWT 1.1.1.1 の実装と、署名・暗号化された JWT トークンを検証し、 org.eclipse.microprofile.jwt.JsonWebToken として表現するための多くのオプションを提供します。

それは quarkus-oidc ベアラートークン認証メカニズムに代わるものを提供します。現在、PEM 鍵または更新可能な JWK 鍵セットを使用して JWT トークンのみを検証することができます。

さらに、 JWT Generation API を提供して、 signed , inner-signed , および/または encrypted `JWT`トークンを簡単に作成することができます。

詳細は、Using SmallRye JWT ガイドを参照してください。

OAuth2

quarkus-elytron-security-oauth2quarkus-oidc Bearer Token 認証メカニズムの代替手段を提供します。これは Elytron をベースにしており、主に不透明なトークンをリモートでイントロスペクトするためのものです。

詳細は、Using OAuth2 ガイドを参照してください。

OpenID Connect、SmallRye JWT、OAuth2 エクステンションのいずれかを選択する

quarkus-oidc エクステンションには、Keycloak のような OpenID Connect プロバイダーが必要で、これは Bearer トークンの検証や Authorization Code Flow によるエンドユーザーの認証に使用することができます。どちらの場合も、quarkus-oidc は、この OpenID Connect プロバイダーへの接続を必要とします。

quarkus-oidc is the only option when the user authentication by using Authorization Code flow or supporting multiple tenants is required. It can also request a UserInfo using both Authorization Code Flow and Bearer access tokens.

ベアラートークンを検証する必要がある場合は、 quarkus-oidcquarkus-smallrye-jwtquarkus-elytron-security-oauth2 を使用できます。

JWT 形式の Bearer トークンを持っている場合は、これら 3 つのエクステンションをすべて使用することができます。quarkus-oidcquarkus-smallrye-jwt の両方は、OpenID Connect プロバイダーがキーをローテーションする際の JsonWebKey (JWK) セットのリフレッシュをサポートします。したがって、リモートトークンのイントロスペクションを回避しなければならない場合や、プロバイダーがサポートしていない場合は、JWT トークンの検証に quarkus-oidc または quarkus-smallrye-jwt を使用する必要があります。

quarkus-smallrye-jwt does not support the remote introspection of the opaque tokens or even JWT tokens - it always relies on the locally available keys - possibly fetched from the OpenID Connect provider. So if you need to introspect the JWT tokens remotely then both quarkus-oidc and quarkus-elytron-security-oauth2 will work. Both extensions also support the verification of the opaque/binary tokens by using the remote introspection.

quarkus-oidcquarkus-smallrye-jwt は、JWT トークンと不透明なトークンの両方をエンドポイントコードに注入することができます。注入された JWT トークンは、ユーザーに関するより豊富な情報を提供することができます。すべてのエクステンションは、 Principal として、トークンを注入することができます。

quarkus-smallrye-jwtquarkus-oidc よりも多くのキーフォーマットをサポートしています。後者は、JWKセットの一部であるJWKフォーマットの鍵のみを使用します。前者では、PEMキーも使用可能です。

quarkus-smallrye-jwt can handle locally not only signed but also inner-signed-and-encrypted or only encrypted tokens. In fact quarkus-oidc and quarkus-elytron-security-oauth2 can verify such tokens too but only by treating them as opaque tokens and verifying them through the remote introspection.

quarkus-elytron-security-oauth2 は、不透明なトークンやJWTトークンをリモートでイントロスペクションするための軽量なライブラリが必要な場合に最適な選択肢です。

不透明なトークンとJWTトークンのどちらを使用するかは、多くの場合、アーキテクチャ上の考慮事項によって決定されることに注意してください。不透明なトークンは、通常、JWT トークンよりもはるかに短いですが、トークンに関連する状態のほとんどをプロバイダのデータベースで維持する必要があります。JWT トークンは、不透明なトークンよりもかなり長いですが、プロバイダは、トークンに関連する状態のほとんどを、トークン・クレームとして保存し、それらに署名や暗号を施すことで、事実上、クライアントに保存を委ねています。

以下、選択肢の概要をご紹介します。

quarkus-oidc quarkus-smallrye-jwt quarkus-elytron-security-oauth2

ベアラー JWTの検証が必要です。

ローカル検証またはイントロスペクション

ローカル検証

イントロスペクション

ベアラー不透明 Tokenの検証が必要です。

イントロスペクション

No

イントロスペクション

JWT トークンを検証するための JsonWebKey セットの更新

Yes

Yes

No

トークンをプリンシパルとして表現

Yes

Yes

Yes

JWT を MP JWT JsonWebToken として挿入

Yes

Yes

No

認可コードフロー

Yes

No

No

マルチテナンシー

Yes

No

No

UserInfo のサポート

Yes

No

No

Pem キー形式のサポート

No

Yes

No

SecretKey のサポート

No

JsonWebKey 形式

No

InnerSigned/Encrypted または Encrypted トークン

イントロスペクション

ローカル検証

イントロスペクション

カスタムトークンの検証

No

インジェクションされたJWTParserで

No

JWT をクッキーとして受け入れる

No

Yes

No

アイデンティティ・プロバイダー

IdentityProvider は、HttpAuthenticationMechanism が提供する認証資格情報を SecurityIdentity に変換します。

Some extensions such as OIDC, OAuth2, SmallRye JWT have the inlined IdentityProvider implementations which are specific to the supported authentication flow. For example, quarkus-oidc uses its own IdentityProvider to convert a token to SecurityIdentity.

Basic または Form HTTP ベースの認証を使用している場合は、ユーザー名とパスワードを SecurityIdentity に変換できる IdentityProvider を追加する必要があります。

認証メカニズムの組み合わせ

異なるソースから認証証明書を取得する場合、複数の認証メカニズムを組み合わせることができます。例えば、組み込みの BasicBearer quarkus-oidc 認証機構を組み合わせることはできますが、quarkus-oidc Bearersmallrye-jwt 認証機構を組み合わせることはできません。なぜなら、両方とも HTTP Authorization Bearer スキームから抽出されたトークンを検証しようとするからです。

パス固有認証メカニズム

特定の要求パスに対して単一の認証メカニズムのみが選択されるように強制できます。以下に例を示します。

quarkus.http.auth.permission.basic-or-bearer.paths=/service
quarkus.http.auth.permission.basic-or-bearer.policy=authenticated

quarkus.http.auth.permission.basic.paths=/basic-only
quarkus.http.auth.permission.basic.policy=authenticated
quarkus.http.auth.permission.basic.auth-mechanism=basic

quarkus.http.auth.permission.bearer.paths=/bearer-only
quarkus.http.auth.permission.bearer.policy=authenticated
quarkus.http.auth.permission.bearer.auth-mechanism=bearer

auth-mechanism プロパティーの値は、basicbearer または form などの HttpAuthenticationMechanism でサポートされている認証スキームと一致する必要があります。

プロアクティブ認証

デフォルトでは、Quarkusはプロアクティブ認証と呼ばれる認証を行います。これは、受信したリクエストにクレデンシャルがある場合、そのリクエストは常に認証されます(ターゲットページが認証を必要としない場合でも)。

詳細については、 プロアクティブ認証を参照してください。

認可

役割ベースのアクセス制御およびその他の認可オプションの詳細については、 セキュリティー認可を参照してください。

カスタマイズやその他の便利なヒント

Quarkus Securityは、高度なカスタマイズが可能です。カスタム HttpAuthenticationMechanismIdentityProviderSecurityidentityAugmentor を登録することができます。

Quarkus Securityのカスタマイズの詳細や、リアクティブセキュリティー、セキュリティープロバイダーの登録などに関する便利なヒントについては、Security Customization を参照してください。

SSL による安全な接続

詳細は、Supporting secure connections with SSL ガイドを参照してください。

クロスオリジンリソース共有

Quarkus アプリケーションを異なるドメインで実行している別のアプリケーションにアクセスできるようにする場合は、CORS (Cross-Origin Resource Sharing) を設定する必要があります。詳細は、HTTP CORS documentation を参照してください。

SameSite クッキー

Quarkus エンドポイントによって設定されたクッキーに SameSite クッキープロパティーを追加する方法の詳細は、SameSite cookies を参照してください。

テスト

Quarkus Securityのテストの詳細については、 セキュリティーのテストを参照してください。

シークレットエンジン

Vault

Quarkus は非常に包括的な HashiCorp Vault のサポートを提供します。詳細は、Quarkus and HashiCorp Vault のドキュメントを参照して下さい。

セキュア・シリアライゼーション

RESTEasy Reactive および Jackson とともにセキュリティーを使用する場合、Quarkus は、設定されたセキュリティーに基づいて、JSON シリアル化に含まれるフィールドを制限できます。詳細は、RESTEasy Reactive documentation を参照してください。

National Vulnerability Database

ほとんどのQuarkusタグは、Common Platform Enumeration (CPE)名の形式で National Vulnerability Database(NVD)に登録されています。登録されているすべてのQuarkusのCPE名は、 この検索クエリを使用して見つけることができます。指定されたCPE名のエントリで表されるQuarkusタグが何らかのCVEの影響を受けている場合、そのCVEへのリンクを辿ることができます。

リストの更新のほか、Quarkus CPE 名のエントリーを関連する CVE に定期的にリンクするよう NVD CPE チームに依頼します。NVD フィードを使用して、アプリケーションのビルド時に脆弱性を検出し、誤検知を確認する OWASP Dependency Check Plugin を使用する場合は、this issue を再び開き、詳細を提供してください。

以下のように、プロジェクトの pom.xmlOWASP Dependency Check Plugin を追加できます。

<plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>${owasp-dependency-check-plugin.version}</version>
</plugin>

where owasp-dependency-check-plugin.version should be set to 7.1.1 or later.

You can configure the plugin like this:

<plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>${owasp-dependency-check-plugin.version}</version>
    <configuration>
        <!-- Fail only when detecting High Vulnerability issues -->
        <failBuildOnCVSS>7</failBuildOnCVSS>
        <suppressionFiles>
            <suppressionFile>${project.basedir}/dependency-cpe-suppression.xml</suppressionFile>
        </suppressionFiles>
    </configuration>
</plugin>

failBuildOnCVSS 値を変更することで、それほど深刻ではない問題も検出できます。

抑制リストは、見逃さないように誤検知をチェックし続けるかどうかによって異なる場合があります。 たとえば、次のようになります:

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.2.xsd">
    <!--
        This is a CPE suppression file for the maven dependency check plugin.
        Each CPE that is found by error (false positive) needs to be suppressed for a specific jar using it's GAV.
        See https://jeremylong.github.io/DependencyCheck/general/suppression.html
     -->
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for netty-tcnative-classes to netty
            ]]>
        </notes>
        <gav regex="true">^io\.netty:netty-tcnative-classes.*:.*$</gav>
        <cpe>cpe:/a:netty:netty</cpe>
    </suppress>
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for Quarkus Mutiny to mutiny:mutiny
            ]]>
        </notes>
        <gav regex="true">^io\.quarkus:quarkus-mutiny.*:.*$</gav>
        <cpe>cpe:/a:mutiny:mutiny</cpe>
    </suppress>
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for Smallrye Mutiny to mutiny:mutiny
            ]]>
        </notes>
        <gav regex="true">^io\.smallrye.reactive:mutiny.*:.*$</gav>
        <cpe>cpe:/a:mutiny:mutiny</cpe>
    </suppress>
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for Smallrye Mutiny to mutiny:mutiny
            ]]>
        </notes>
        <gav regex="true">^io\.smallrye.reactive:smallrye-mutiny.*:.*$</gav>
        <cpe>cpe:/a:mutiny:mutiny</cpe>
    </suppress>
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for Smallrye Mutiny to mutiny:mutiny
            ]]>
        </notes>
        <gav regex="true">^io\.smallrye.reactive:vertx-mutiny.*:.*$</gav>
        <cpe>cpe:/a:mutiny:mutiny</cpe>
    </suppress>
    <suppress>
        <notes>
            <![CDATA[
                Suppress the false positive CPE for graal-sdk to GraalVM (the JVM distribution)
            ]]>
        </notes>
        <gav regex="true">^org\.graalvm\.sdk:graal-sdk:.*$</gav>
        <cpe>cpe:/a:oracle:graalvm</cpe>
    </suppress>
</suppressions>

Such a suppression list has to be carefully prepared and revisited from time to time. You should consider making individual suppressions time limited by adding an until attribute, for example: <suppress until="2022-01-01Z">…​</suppress>. It will let you doublecheck that only the same known false positives are reported when the suppression period expires, and after reviewing the report you can set a new expiry date.