ウェブエンドポイントの認可
Quarkus has an integrated pluggable web security layer. If security is enabled, all HTTP requests will have a permission check performed to make sure they are allowed to continue.
This means you cannot use @PermitAll to open a path if the path is blocked by the quarkus.http.auth. configuration.
|
If you are using JAX-RS, consider using |
認可は、セキュリティ・プロバイダーが提供するユーザー・ロールに基づきます。これらのロールをカスタマイズするには、 SecurityIdentityAugmentor を作成することができます。 セキュリティ・アイデンティティのカスタマイズ を参照してください。
設定を利用した認可
Quarkusの設定では、パーミッション・セットを使用してパーミッションが定義され、各パーミッション・セットはアクセス制御のポリシーを指定します。
組込ポリシー |
説明 |
|
このポリシーは、すべてのユーザーを拒否します。 |
|
このポリシーは、すべてのユーザーを許可します。 |
|
このポリシーは、認証されたユーザーのみを許可します。 |
指定したロールを持つユーザーにリソースへのアクセスを許可するロールベースのポリシーを定義することができます。
quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin (1)
| 1 | This defines a role-based policy that allows users with the user and admin roles.
Such a custom policy can be referenced by permission sets just like the built-in ones, as shown in the example below. |
パーミッションセットは、 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 | This permission references the default permit built-in policy to allow GET methods to /public.
In this case, the demonstrated setting would not affect this example because this request is allowed anyway. |
| 2 | このパーミッションは /forbidden に対する組み込みの deny ポリシーを参照します。これは * で終わらないので、完全なパスマッチとなります。 |
| 3 | This is a permission set that references the previously defined policy.
roles1 is an example name; you can call the permission sets whatever you want. |
パスとメソッドのマッチング
Permission sets can also specify paths and methods as a comma-separated list.
If a path ends with the * wildcard, the query it generates matches all sub-paths.
Otherwise, it queries for an exact match and will only match that specific path:
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 therefore 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.
|
|
Subpath permissions always win against the root path permissions, as explained above in the
|
複数のパスのマッチング:一番具体的なパスが勝ちます
When a path is registered with multiple permission sets, the permission sets that explicitly specify an HTTP method that matches the request will take precedence. In this instance, the permission sets without methods will only come into effect if the request method does not match permission sets with the method specification.
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
|
上記のパーミッション・セットの場合、 一方、 |
複数のパスのマッチング:一番長いパスが勝ちます
Sometimes, the previously described rules allow multiple permission sets to win at the same time. In that case, for the request to proceed, all the permissions must allow access. Note that for this to happen, both have to either have specified the method or have no method. Method-specific matches take precedence.
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 は両方のパーミッションセットのパスにマッチするので、 user と admin の両方のロールが必要になります。
|
アクセスを拒否するための設定プロパティ
以下の設定により、ロールベースアクセスコントロール(RBAC)の拒否動作が変更されます:
quarkus.security.jaxrs.deny-unannotated-endpoints=true|false-
If set to true, access is denied for all JAX-RS endpoints by default. If a JAX-RS endpoint does not have any security annotations, it defaults to the
@DenyAllbehavior. This is useful to ensure you cannot accidentally expose an endpoint that is supposed to be secured. Defaults tofalse. quarkus.security.jaxrs.default-roles-allowed=role1,role2-
Defines the default role requirements for unannotated endpoints. The
**role is a special role that means any authenticated user. This cannot be combined withdeny-unannotated-endpoints, asdenytakes the effect instead. 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ルートパス
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 comes with built-in security to allow for Role-Based Access Control (RBAC)
based on the common security annotations @RolesAllowed, @DenyAll, @PermitAll on REST endpoints and CDI beans.
アノテーション型 |
説明 |
@DenyAll |
どのセキュリティロールも指定されたメソッドを呼び出すことを許可されていないことを指定します。 |
@PermitAll |
すべてのセキュリティロールが指定されたメソッドを呼び出すことを許可されているように指定します。
|
@RolesAllowed |
アプリケーション内のメソッドへのアクセスが許可されているセキュリティロールのリストを指定します。
|
SubjectExposingResourceの例 featured in this chapter demonstrates an endpoint that uses both JAX-RS and Common Security annotations to describe and secure its endpoints.
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 アノテーションを宣言しているため、呼び出すユーザーに関係なく、REST メソッドとして直接アクセスすることはすべて禁止されています。このメソッドは、このクラスの他のメソッドから内部的に呼び出すことは可能です。 |
| Please refer to the Proactive Authentication section of the Built-In Authentication Support guide if you plan to use standard security annotations on the IO thread. |
The @RolesAllowed annotation value supports Property Expressions including default values and nested Property Expressions.
Configuration properties used with the annotation are resolved at runtime.
アノテーション |
値の説明 |
|
エンドポイントは、 |
|
値が複数の変数を含むことができることを示す例。 |
|
デフォルト値の実証。
必要な役割は |
@RolesAllowed アノテーションにおけるプロパティ式の使用例admin=Administrator
tester.group=Software
tester.role=Tester
%prod.secured=User
%dev.secured=**
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("admin")
@RolesAllowed("${admin}") (1)
public String getSubjectSecuredAdmin(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
String name = user != null ? user.getName() : "anonymous";
return name;
}
@GET
@Path("software-tester")
@RolesAllowed("${tester.group}-${tester.role}") (2)
public String getSubjectSoftwareTester(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
String name = user != null ? user.getName() : "anonymous";
return name;
}
@GET
@Path("user")
@RolesAllowed("${customer:User}") (3)
public String getSubjectUser(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
String name = user != null ? user.getName() : "anonymous";
return name;
}
@GET
@Path("secured")
@RolesAllowed("${secured}") (4)
public String getSubjectSecured(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
String name = user != null ? user.getName() : "anonymous";
return name;
}
}
| 1 | @RolesAllowed アノテーション値は、 Administrator の値に設定されています。 |
| 2 | This /subject/software-tester endpoint requires an authenticated user that has been granted the role "Software-Tester".
It is possible to use multiple expressions in the role definition. |
| 3 | 設定プロパティ customer を設定していないため、 @RolesAllowed("${customer:User}") アノテーションの使用によって、この /subject/user エンドポイントには"User"というロールを付与された認証ユーザーが必要です。 |
| 4 | この /subject/secured エンドポイントは、本番環境では User のロールを与えられた認証ユーザーが必要ですが、開発モードではどのような認証ユーザーでも許可されます。 |