Authorization of Web Endpoints
Quarkusには、プラグイン可能なウェブセキュリティーレイヤーが統合されています。セキュリティーが有効になっている場合、すべてのHTTPリクエストは、処理の継続が許可されているかどうかを確認するためのパーミッションチェックが実行されます。
Configuration authorization checks are executed before any annotation-based authorization check is done, so both
checks have to pass for a request to be allowed. This means you cannot use @PermitAll to open up a path if the path has
been blocked using quarkus.http.auth. configuration. If you are using JAX-RS you may want to consider using the
quarkus.security.jaxrs.deny-unannotated-endpoints or quarkus.security.jaxrs.default-roles-allowed to set default security
requirements instead of HTTP path level matching, as these properties can be overridden by annotations on an individual
endpoint.
|
認可は、セキュリティプロバイダが提供するユーザーロールに基づいて行われます。 これらのロールをカスタマイズするために、 SecurityIdentityAugmentor を作成することができます。Security Identity Customization を参照してください。
設定を利用した認可
デフォルトの実装では、 application.properties の 設定を使用してパーミッションを定義することができます。以下に config の例を示します。
quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin (1)
quarkus.http.auth.permission.roles1.paths=/roles-secured/*,/other/*,/api/* (2)
quarkus.http.auth.permission.roles1.policy=role-policy1
quarkus.http.auth.permission.permit1.paths=/public/* (3)
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET
quarkus.http.auth.permission.deny1.paths=/forbidden (4)
quarkus.http.auth.permission.deny1.policy=deny
| 1 | これは、 user と admin のロールを持つユーザーを許可するロールベースのポリシーを定義します。これは後のルールで参照されます。 |
| 2 | これは以前に定義されたポリシーを参照するパーミッションセットです。 roles1 は任意の名前ですので、好きなようにパーミッションセットを呼び出すことができます。 |
| 3 | このパーミッションはデフォルトの permit ビルトインポリシーを参照して、 /public への GET メソッドを許可します。この例では、このリクエストはいずれにせよ許可されているはずなので、これは実際には no-op です。 |
| 4 | このパーミッションは /forbidden に対する組み込みの deny ポリシーを参照します。これは * で終わらないので、完全なパスマッチとなります。 |
パーミッションは、パーミッションセットを使ってコンフィグで定義されます。これらは任意の名前のパーミッション・グルーピングです。各パーミッションセットには、アクセスを制御するためのポリシーを指定する必要があります。組み込みのポリシーには, deny , permit , authenticated の3種類があり,それぞれ,すべてを許可,すべてを拒否,認証されたユーザのみを許可 となります。
また、例に示すように、ロールベースのポリシーを定義することも可能です。これらのポリシーでは、指定されたロールを持つユーザーにのみ、リソースへのアクセスを許可します。
パス、メソッドでのマッチング
パーミッションセットでは、パスとメソッドをカンマ区切りのリストで指定することもできます。パスの末尾が * である場合はワイルドカードマッチとみなされ、すべてのサブパスにマッチしますが、そうでない場合は完全一致となり、特定のパスにのみマッチします。
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
パスはマッチするがメソッドはマッチしない場合
リクエストがパスに基づいて1つ以上のパーミッションセットにマッチするが、 メソッドの要件によりマッチしない場合、そのリクエストは拒否されます。
Given the above permission set, GET /public/foo would match both the path and method and thus be allowed,
whereas POST /public/foo would match the path but not the method and would thus be rejected.
|
複数のパスのマッチング:一番長いパスが勝ちます。
マッチングは常にロンゲストパス に基づいて行われ、より具体的なパーミッションセットがマッチした場合、それより具体的でないパーミッションセットは考慮されません。:
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
Given the above permission set, GET /public/forbidden-folder/foo would match both permission sets' paths,
but because it matches the deny1 permission set’s path on a longer match, deny1 will be chosen and the request will
be rejected.
|
|
サブパス パーミッションは、上述の
|
複数のパスのマッチング:一番具体的なパスが勝ちます
パスが複数の許可セットで登録されている場合、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
Given the above permission set, GET /public/foo would match both permission sets' paths,
but because it matches the permit1 permission set’s explicit method, permit1 will be chosen and the request will
be accepted. PUT /public/foo on the other hand, will not match the method permissions of permit1 and so
deny1 will be activated and reject the request.
|
複数のパスのマッチング:一番長いパスが勝ちます
複数のパーミッションセットが同じパスとメソッドを指定している場合(または複数のパーミッションがメソッドを持たない場合)、リクエストを進めるためには両方のパーミッションがアクセスを許可しなければなりません。これを実現するためには、両方がメソッドを指定しているか、メソッドを持たないかのいずれかでなければならないことに注意してください、メソッド固有のマッチは上記のように優先されます。 :
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
Given the above permission set, GET /api/foo would match both permission sets' paths,
so would require both the user and admin roles.
|
アクセスを拒否する設定プロパティー
RBACのDeny動作を変更する設定は3つあります。 :
quarkus.security.jaxrs.deny-unannotated-endpoints=true|false-
この値をtrue に設定すると、デフォルトですべての JAX-RS エンドポイントに対してアクセスが拒否されます。したがって、JAX-RS エンドポイントがセキュリティアノテーションを持っていない場合、デフォルトで
@DenyAllの動作になります。これは、セキュリティで保護されているはずのエンドポイントを誤って公開してしまわないようにするために有用です。デフォルトはfalseです。 quarkus.security.jaxrs.default-roles-allowed=role1,role2-
アノテーションされていないエンドポイントのデフォルトのロール要件を定義します。ロール「**」は、認証された任意のユーザを意味する特別なロールです。これは、代わりにdenyが有効になるため、
deny-unannotated-endpointsと組み合わせることはできません。 quarkus.security.deny-unannotated-members=true|false-
-
この値をtrue に設定すると、セキュリティアノテーションを持つメソッドを含むクラスで定義されているものの、セキュリティアノテーションを持たないすべての CDI メソッドと JAX-RS エンドポイントへのアクセスが拒否されるようになります。デフォルトは
falseです。
-
権限の無効化
パーミッションは、宣言されたパーミッションごとの 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.
パーミッションパスとhttp rootパス
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 から提供されるリソースにのみ影響します。 quarkus.http.root-path が / 以外に設定されている場合、アプリケーションリソースと一致しない可能性があります。
詳細については、 Quarkusのパス解決 を参照してください。
アノテーションを使った認可
Quarkusには、共通のセキュリティーアノテーション( @RolesAllowed , @DenyAll , @PermitAll )に基づいたロールベースのアクセス制御 (RBAC )をRESTエンドポイントとCDI Bean上で可能にするためのビルトインセキュリティーが搭載されています。JAX-RSとCommon Securityアノテーションの両方を利用してエンドポイントを記述し、セキュリティーを確保するエンドポイントの例は、 [subject-example] に記載されています。Quarkusはまた、認証済みのユーザーがリソースにアクセスすることを許可する io.quarkus.security.Authenticated アノテーションも提供しています( @RolesAllowed("**") と同等です)。
import java.security.Principal;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;
@Path("subject")
public class SubjectExposingResource {
@GET
@Path("secured")
@RolesAllowed("Tester") (1)
public String getSubjectSecured(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal(); (2)
String name = user != null ? user.getName() : "anonymous";
return name;
}
@GET
@Path("unsecured")
@PermitAll (3)
public String getSubjectUnsecured(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal(); (4)
String name = user != null ? user.getName() : "anonymous";
return name;
}
@GET
@Path("denied")
@DenyAll (5)
public String getSubjectDenied(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
String name = user != null ? user.getName() : "anonymous";
return name;
}
}
| 1 | この /subject/secured エンドポイントは、 @RolesAllowed("Tester") アノテーションを使用して"Tester"というロールを付与された認証済みユーザーが必要です。 |
| 2 | エンドポイントは、JAX-RS SecurityContext からユーザー・プリンシパルを取得します。これは、保護されたエンドポイントの場合は非 null になります。 |
| 3 | /subject/unsecured エンドポイントでは、 @PermitAll アノテーションを指定することで、認証されていないアクセスが可能になります。 |
| 4 | ユーザープリンシパルを取得するためのこの呼び出しは、呼び出し元が認証されていない場合はnullを返し、呼び出し元が認証されている場合は非nullを返します。 |
| 5 | /subject/denied エンドポイントは、 @DenyAll アノテーションを指定することで、呼出が認証されているかどうかにかかわらず、あらゆるアクセスを禁止します。 |