第1章 Web エンドポイントの認可


Quarkus には、プラグ可能な Web セキュリティーレイヤーが組み込まれています。セキュリティーが有効な場合、システムはすべての HTTP リクエストに対して権限チェックを実行し、リクエストを続行するかどうかを決定します。

quarkus.http.auth. 設定によってパスが制限されている場合は、@PermitAll を使用してもパスは開きません。特定のパスにアクセスできるようにするには、Quarkus のセキュリティー設定内で適切な設定を行う必要があります。

注記

Jakarta RESTful Web サービスを使用する場合は、HTTP パスレベルのマッチングではなく、quarkus.security.jaxrs.deny-unannotated-endpoints または quarkus.security.jaxrs.default-roles-allowed を使用してデフォルトのセキュリティー要件を設定することを検討してください。アノテーションによって、個々のエンドポイントでこれらのプロパティーをオーバーライドできるためです。

認可は、セキュリティープロバイダーが提供するユーザーロールに基づいて行われます。ユーザーロールをカスタマイズするには、SecurityIdentityAugmentor を作成します。Security Identity Customization を参照してください。

1.1. 設定を使用した認可

権限は、Quarkus 設定で権限セットによって定義されます。各権限セットで、アクセス制御用のポリシーを指定します。

表1.1 Red Hat build of Quarkus のポリシーの概要
組み込みのポリシー説明

deny

このポリシーはすべてのユーザーを拒否します。

permit

このポリシーはすべてのユーザーを許可します。

authenticated

このポリシーは認証済みユーザーのみを許可します。

特定のロールを持つユーザーにリソースへのアクセスを許可するロールベースのポリシーを定義できます。

ロールベースのポリシーの例

quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin                  1

1
これは、user ロールと admin ロールを持つユーザーを許可するロールベースのポリシーを定義します。

次の設定例に示すように、application.properties ファイルで定義されている組み込みの権限セットを設定することで、カスタムポリシーを参照できます。

ポリシー設定の例

quarkus.http.auth.permission.permit1.paths=/public/*                            1
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET

quarkus.http.auth.permission.deny1.paths=/forbidden                             2
quarkus.http.auth.permission.deny1.policy=deny

quarkus.http.auth.permission.roles1.paths=/roles-secured/*,/other/*,/api/*      3
quarkus.http.auth.permission.roles1.policy=role-policy1

1
この権限は、デフォルトの組み込みの permit ポリシーを参照して、/public への GET メソッドを許可します。この場合、このリクエストはいずれにせよ許可されるため、上記の設定はこの例に影響しません。
2
この権限は、/forbidden の組み込み deny ポリシーを参照します。末尾が * でないため、これはパスの完全一致です。
3
この権限セットは、以前に定義されたポリシーを参照します。roles1 は例の名前です。権限セットには任意の名前を付けることができます。
警告

この例の正確なパス /forbidden では、/forbidden/ パスは保護されません。セキュリティーの対象範囲を適切なものにするには、/forbidden/ パスの正確なパスを新しく追加する必要があります。

1.1.1. カスタムの HttpSecurityPolicy

場合によっては、独自の名前付きポリシーを登録すると便利です。これを実行するには、io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy インターフェイスを実装するアプリケーションスコープの CDI Bean を作成します。以下にその例を示します。

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy;
import io.smallrye.mutiny.Uni;
import io.vertx.ext.web.RoutingContext;

@ApplicationScoped
public class CustomNamedHttpSecPolicy implements HttpSecurityPolicy {
    @Override
    public Uni<CheckResult> checkPermission(RoutingContext event, Uni<SecurityIdentity> identity,
            AuthorizationRequestContext requestContext) {
        if (customRequestAuthorization(event)) {
            return Uni.createFrom().item(CheckResult.PERMIT);
        }
        return Uni.createFrom().item(CheckResult.DENY);
    }

    @Override
    public String name() {
        return "custom"; 1
    }

    private static boolean customRequestAuthorization(RoutingContext event) {
        // here comes your own security check
        return !event.request().path().endsWith("denied");
    }
}
1
名前付き HTTP セキュリティーポリシーは、application.properties パスマッチングルールにマッチするリクエストにのみ適用されます。

設定ファイルから参照されるカスタム名の HttpSecurityPolicy の例

quarkus.http.auth.permission.custom1.paths=/custom/*
quarkus.http.auth.permission.custom1.policy=custom                              1

1
カスタムポリシー名は、io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.name メソッドによって返される値とマッチする必要があります。
ヒント

すべてのリクエストで呼び出されるグローバルの HttpSecurityPolicy を作成することもできます。io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.name メソッドを実装せず、ポリシーに名前を付けないままにしてください。

1.1.2. パスとメソッドのマッチング

権限セットでは、パスとメソッドをコンマ区切りリスト形式で指定することもできます。パスの末尾がワイルドカード * の場合は、そのパスによって生成されたクエリーがすべてのサブパスにマッチします。それ以外の場合、クエリーは完全一致を照会し、特定のパスにのみマッチします。

quarkus.http.auth.permission.permit1.paths=/public*,/css/*,/js/*,/robots.txt    1
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD
1
パスの末尾の * ワイルドカードは、0 個以上のパスセグメントにマッチしますが、/public パスから始まる単語にはマッチしません。そのため、/public-info のようなパスはこのパターンにマッチしません。

1.1.3. パスにはマッチするがメソッドにはマッチしない場合

パスに基づいて 1 つ以上の権限セットにマッチしても、必要なメソッドのいずれにもマッチしない場合、リクエストは拒否されます。

ヒント

上記の権限セットが指定されている場合、GET/public/foo は、パスとメソッドの両方にマッチするため、許可されます。対照的に、POST/public/foo は、パスにはマッチしますが、メソッドにはマッチしないため、拒否されます。

1.1.4. 複数のパスのマッチング: 最長パスが優先される

マッチングは、常に "最長パスが優先される" という基準で行われます。より詳細な権限セットがマッチした場合、それよりも詳細でない権限セットは考慮されません。

quarkus.http.auth.permission.permit1.paths=/public/*
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD

quarkus.http.auth.permission.deny1.paths=/public/forbidden-folder/*
quarkus.http.auth.permission.deny1.policy=deny
ヒント

上記の権限セットの場合、GET /public/forbidden-folder/foo は、両方の権限セットのパスとマッチします。しかし、より長いパスが deny1 権限セットのパスとマッチするため、deny1 が選択され、リクエストが拒否されます。

注記

前述の deny1 権限と permit1 権限の例で示したように、サブパスの権限がルートパスの権限よりも優先されます。

このルールをさらに例示するために、サブパス権限ではパブリックリソースへのアクセスを許可し、ルートパス権限では認可を要求するシナリオを示します。

quarkus.http.auth.policy.user-policy.roles-allowed=user
quarkus.http.auth.permission.roles.paths=/api/*
quarkus.http.auth.permission.roles.policy=user-policy

quarkus.http.auth.permission.public.paths=/api/noauth/*
quarkus.http.auth.permission.public.policy=permit

1.1.5. 複数のサブパスのマッチング: * ワイルドカードへの最長パスが優先される

前の例では、パスの末尾が * ワイルドカードの場合に、すべてのサブパスがマッチすることを示しました。

このワイルドカードは、パスの途中にも適用され、単一のパスセグメントを表します。他のパスセグメント文字と混在させることはできません。したがって、/public/*/about-us パスのように、* ワイルドカードは常にパス区切り文字によって囲まれます。

複数のパスパターンが同じリクエストパスに対応する場合、システムは * ワイルドカードに至る最長のサブパスを選択します。この場合は、すべてのパスセグメント文字が * ワイルドカードよりも詳細なものとして扱われます。

以下は簡単な例です。

quarkus.http.auth.permission.secured.paths=/api/*/detail                    1
quarkus.http.auth.permission.secured.policy=authenticated
quarkus.http.auth.permission.public.paths=/api/public-product/detail        2
quarkus.http.auth.permission.public.policy=permit
1
/api/product/detail などのリクエストパスには、認証済みユーザーのみがアクセスできます。
2
パス /api/public-product/detail はより詳細であるため、どのユーザーもアクセスできます。
重要

認可を使用した設定で保護するパスは、すべてテストする必要があります。複数のワイルドカードを使用してパスパターンを記述するのは、手間がかかる場合があります。パスが意図したとおりに認可されていることを確認してください。

次の例では、パスは最も詳細なものから最も詳細でないものの順に並べられています。

最も詳細なパスから最も詳細でないパスの順に並べたリクエストパス /one/two/three/four/five のマッチ

/one/two/three/four/five
/one/two/three/four/*
/one/two/three/*/five
/one/two/three/*/*
/one/two/*/four/five
/one/*/three/four/five
/*/two/three/four/five
/*/two/three/*/five
/*

重要

パスの末尾の * ワイルドカードは、0 個以上のパスセグメントとマッチします。その他の場所に指定された * ワイルドカードは、1 つのパスセグメントに完全一致します。

1.1.6. 複数のパスのマッチング: 最も詳細なメソッドが優先される

パスが複数の権限セットに登録されている場合は、リクエストにマッチする HTTP メソッドを明示的に指定している権限セットが優先されます。この場合、メソッドのない権限セットが適用されるのは、リクエストメソッドがメソッドの指定を持つ権限セットとマッチしない場合に限られます。

quarkus.http.auth.permission.permit1.paths=/public/*
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD

quarkus.http.auth.permission.deny1.paths=/public/*
quarkus.http.auth.permission.deny1.policy=deny
注記

上記の権限セットは、GET/public/foo が両方の権限セットのパスにマッチすることを示しています。ただし、これは permit1 権限セットの明示的なメソッドと明確に一致しています。したがって、permit1 が選択され、リクエストが受け入れられます。

対照的に、PUT/public/foo は、permit1 のメソッド権限とマッチしません。その結果、deny1 がアクティブになり、リクエストが拒否されます。

1.1.7. 複数のパスとメソッドのマッチング: どちらも優先される

場合によっては、前述のルールにより、複数の権限セットが同時に適用されることがあります。その場合、リクエストを続行するには、すべての権限でアクセスが許可されている必要があります。これを実現するには、両方にメソッドを追加するか、両方からメソッドを除外する必要があります。メソッド固有のマッチが優先されます。

quarkus.http.auth.policy.user-policy1.roles-allowed=user
quarkus.http.auth.policy.admin-policy1.roles-allowed=admin

quarkus.http.auth.permission.roles1.paths=/api/*,/restricted/*
quarkus.http.auth.permission.roles1.policy=user-policy1

quarkus.http.auth.permission.roles2.paths=/api/*,/admin/*
quarkus.http.auth.permission.roles2.policy=admin-policy1
ヒント

上記の権限セットの場合、GET /api/foo は両方の権限セットのパスにマッチするため、useradmin の両方のロールが必要です。

1.1.8. アクセスを拒否するための設定プロパティー

次の設定は、ロールベースのアクセス制御 (RBAC) の拒否動作を変更するものです。

quarkus.security.jaxrs.deny-unannotated-endpoints=true|false
true に設定すると、すべての Jakarta REST エンドポイントへのアクセスがデフォルトで拒否されます。Jakarta REST エンドポイントにセキュリティーアノテーションがない場合は、エンドポイントのデフォルトが @DenyAll 動作になります。これにより、保護されているはずのエンドポイントが誤って公開されることを回避できます。デフォルトは false です。
quarkus.security.jaxrs.default-roles-allowed=role1,role2
アノテーションのないエンドポイントのデフォルトのロール要件を定義します。** ロールは、すべての認証済みユーザーを意味する特別なロールです。これを deny-unannotated-endpoints と組み合わせることはできません。代わりに deny が有効になるためです。
quarkus.security.deny-unannotated-members=true|false
true に設定すると、セキュリティーアノテーションを持たないが、セキュリティーアノテーションを持つメソッドを含むクラスで定義されているすべての CDI メソッドと Jakarta REST エンドポイントへのアクセスが拒否されます。デフォルトは false です。

1.1.9. 権限の無効化

次のように、宣言された各権限に対して enabled プロパティーを設定することで、ビルド時に権限を無効にすることができます。

quarkus.http.auth.permission.permit1.enabled=false
quarkus.http.auth.permission.permit1.paths=/public/*,/css/*,/js/*,/robots.txt
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD

権限は、システムプロパティーまたは環境変数 (例: -Dquarkus.http.auth.permission.permit1.enabled=true) を使用して実行時に再度有効にできます。

1.1.10. 権限パスと HTTP ルートパス

quarkus.http.root-path 設定プロパティーは、http エンドポイントのコンテキストパス を変更します。

デフォルトでは、quarkus.http.root-path は設定した権限パスの先頭に自動的に追加されるため、スラッシュを使用しないでください。次に例を示します。

quarkus.http.auth.permission.permit1.paths=public/*,css/*,js/*,robots.txt

この設定は次のものと同等です。

quarkus.http.auth.permission.permit1.paths=${quarkus.http.root-path}/public/*,${quarkus.http.root-path}/css/*,${quarkus.http.root-path}/js/*,${quarkus.http.root-path}/robots.txt

先頭にスラッシュを付けると、設定された権限パスの解釈方法が変わります。設定された URL がそのまま使用され、quarkus.http.root-path の値が変更されても、パスが調整されません。

例:

quarkus.http.auth.permission.permit1.paths=/public/*,css/*,js/*,robots.txt

この設定は、固定または静的 URL /public から提供されるリソースにのみ影響します。この URL は、quarkus.http.root-path/ 以外に設定されていると、アプリケーションリソースとマッチしない可能性があります。

詳細は、Path Resolution in Quarkus を参照してください。

1.1.11. SecurityIdentity ロールのマッピング

優先されるロールベースのポリシーにより、SecurityIdentity ロールをデプロイメント固有のロールにマッピングできます。その後、デプロイメント固有のロールを、@RolesAllowed アノテーションを使用してエンドポイント認可に適用できます。

quarkus.http.auth.policy.admin-policy1.roles.admin=Admin1 1
quarkus.http.auth.permission.roles1.paths=/*
quarkus.http.auth.permission.roles1.policy=admin-policy1
1
admin ロールを Admin1 ロールにマッピングします。SecurityIdentityadminAdmin1 の両方のロールが付与されます。

1.1.12. 共有権限チェック

非共有権限チェックの重要なルールの 1 つは、最も詳細なパスのマッチが 1 つだけ適用されることです。もちろん、同じ優先パスを持つ権限を必要なだけ指定することができます。それらはすべて適用されます。しかし、何度も繰り返さずに、権限チェックを多くのパスに適用したいという場合もあるでしょう。そのような場合は、共有権限チェックが有用です。共有権限チェックは、権限パスがマッチしたときに常に適用されます。

すべての HTTP リクエストに適用されるカスタム名の HttpSecurityPolicy の例

quarkus.http.auth.permission.custom1.paths=/*
quarkus.http.auth.permission.custom1.shared=true    1
quarkus.http.auth.permission.custom1.policy=custom

quarkus.http.auth.policy.admin-policy1.roles-allowed=admin
quarkus.http.auth.permission.roles1.paths=/admin/*
quarkus.http.auth.permission.roles1.policy=admin-policy1

1
カスタムの HttpSecurityPolicy も、admin-policy1 ポリシーとともに /admin/1 パスに適用されます。
ヒント

共有権限チェックを多数設定することは、非共有権限チェックを設定する場合よりも効果が低くなります。以下の例のように、共有権限を使用して非共有権限チェックを補完してください。

共有権限を持つ SecurityIdentity ロールのマッピング

quarkus.http.auth.policy.role-policy1.roles.root=admin,user 1
quarkus.http.auth.permission.roles1.paths=/secured/*        2
quarkus.http.auth.permission.roles1.policy=role-policy1
quarkus.http.auth.permission.roles1.shared=true

quarkus.http.auth.policy.role-policy2.roles-allowed=user    3
quarkus.http.auth.permission.roles2.paths=/secured/user/*
quarkus.http.auth.permission.roles2.policy=role-policy2

quarkus.http.auth.policy.role-policy3.roles-allowed=admin
quarkus.http.auth.permission.roles3.paths=/secured/admin/*
quarkus.http.auth.permission.roles3.policy=role-policy3

1
ロール root は、/secured/user/* および /secured/admin/* パスにアクセスできるようになります。
2
/secured/* パスには認証済みユーザーのみがアクセスできます。これにより、/secured/all パスなどが保護されます。
3
共有権限は常に非共有権限の前に適用されるため、root ロールを持つ SecurityIdentity には user ロールも付与されます。
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

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

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

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

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

会社概要

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

© 2024 Red Hat, Inc.