Quarkus の認証メカニズム
Quarkus Security フレームワークは、複数の認証メカニズムをサポートしており、これらを使用してアプリケーションを保護することができます。また、認証メカニズムを組み合わせることも可能です。
|
Quarkus アプリケーションを保護するための認証メカニズムを選択する前に、提供される情報を確認してください。 |
サポートされる認証メカニズムの概要
サポートされている認証メカニズムは、Quarkus に組み込まれているものもあれば、エクステンションを追加する必要があるものもあります。これらのメカニズムについては、次のセクションで詳しく説明します。
次の表は、特定の認証要件と、Quarkus で使用できるサポートされるメカニズムを対応付けたものです。
| 認証要件 | 認証メカニズム |
|---|---|
ユーザー名とパスワード |
|
ベアラーアクセストークン |
|
シングルサインオン (SSO) |
|
クライアント証明書 |
|
WebAuthn |
|
Kerberos チケット |
詳細は、以下の トークン認証メカニズムの比較 の表をご覧ください。
組込認証メカニズム
Quarkus Security には、次のような組込の認証サポートがあります。
フォームベース認証
Quarkus は、従来の Servlet フォームベース認証と同様に動作するフォームベース認証を提供します。従来のフォーム認証とは異なり、Quarkus はクラスター化された HTTP セッションをサポートしていないため、認証されたユーザーは HTTP セッションに保存されません。代わりに、認証情報は暗号化された Cookie に保存され、同じ暗号化キーを共有するすべてのクラスターメンバーが読み取ることができます。
暗号化を適用するには、 quarkus.http.auth.session.encryption-key プロパティーを追加し、設定する値が 16 文字以上であることを確認してください。暗号化キーは SHA-256 を使用してハッシュ化されます。結果のダイジェストは、Cookie 値の AES-256 暗号化のキーとして使用されます。Cookie には暗号化された値の一部として有効期限が含まれているため、クラスター内のすべてのノードのクロックが同期されている必要があります。セッションが使用中であれば、1 分間隔で有効期限が更新された新しい Cookie が生成されます。
フォーム認証を開始するには、Basic 認証の有効化 で説明されているのと同様の設定が必要であり、プロパティー quarkus.http.auth.form.enabled を true に設定する必要があります。
フォームベース認証を使用した単純な application.properties は次のようになります。
quarkus.http.auth.form.enabled=true
quarkus.http.auth.form.login-page=login.html
quarkus.http.auth.form.landing-page=hello
quarkus.http.auth.form.error-page=
# Define testing user
quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.security.users.embedded.users.alice=alice
quarkus.security.users.embedded.roles.alice=user
|
application.properties ファイルでユーザー名、シークレット、およびロールを設定することは、テストシナリオにのみ適しています。実稼働アプリケーションを保護するには、データベースまたは LDAP を使用してこの情報を格納することが重要です。詳細は、Quarkus Security と Jakarta Persistence または Basic 認証の有効化 に記載されているその他の情報を参照してください。 |
アプリケーションのログインページには、以下と同様の HTML フォームが含まれます。
<form action="/j_security_check" method="post">
<label>Username</label>
<input type="text" placeholder="Username" name="j_username" required>
<label>Password</label>
<input type="password" placeholder="Password" name="j_password" required>
<button type="submit">Login</button>
</form>
シングルページアプリケーション (SPA) では、通常、次の例に示すように、デフォルトのページパスを削除してリダイレクトを回避する必要があります。
# do not redirect, respond with HTTP 200 OK
quarkus.http.auth.form.landing-page=
# do not redirect, respond with HTTP 401 Unauthorized
quarkus.http.auth.form.login-page=
quarkus.http.auth.form.error-page=
# HttpOnly must be false if you want to log out on the client; it can be true if logging out from the server
quarkus.http.auth.form.http-only-cookie=false
SPA のリダイレクトを無効にしたので、クライアントからプログラムによってログインおよびログアウトする必要があります。以下は、 j_security_check エンドポイントにログインし、Cookie を破棄してアプリケーションからログアウトするための JavaScript メソッドの例です。
const login = () => {
// Create an object to represent the form data
const formData = new URLSearchParams();
formData.append("j_username", username);
formData.append("j_password", password);
// Make an HTTP POST request using fetch against j_security_check endpoint
fetch("j_security_check", {
method: "POST",
body: formData,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then((response) => {
if (response.status === 200) {
// Authentication was successful
console.log("Authentication successful");
} else {
// Authentication failed
console.error("Invalid credentials");
}
})
.catch((error) => {
console.error(error);
});
};
クライアントから SPA をログアウトするには、Cookie を quarkus.http.auth.form.http-only-cookie=false に設定して、Cookie を破棄し、メインページにリダイレクトできるようにする必要があります。
const logout= () => {
// delete the credential cookie, essentially killing the session
const removeCookie = `quarkus-credential=; Max-Age=0;path=/`;
document.cookie = removeCookie;
// perform post-logout actions here, such as redirecting back to your login page
};
サーバーから SPA をログアウトするには、Cookie を quarkus.http.auth.form.http-only-cookie=true に設定し、このサンプルコードを使用して Cookie を破棄できます。
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.FormAuthenticationMechanism;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.POST;
@Inject
SecurityIdentity identity;
@POST
public Response logout() {
if (identity.isAnonymous()) {
throw new UnauthorizedException("Not authenticated");
}
FormAuthenticationMechanism.logout(identity); (1)
return Response.noContent().build();
}
| 1 | セッション Cookie を削除してログアウトを実行します。 |
フォームベース認証の設定リファレンス
フォームベース認証の設定には、以下のプロパティーを使用できます。
ビルド時に固定される設定プロパティ - その他の設定プロパティは実行時にオーバーライド可能です。
Configuration property |
タイプ |
デフォルト |
|---|---|---|
Determines whether the entire permission set is enabled, or not. By default, if the permission set is defined, it is enabled. Environment variable: Show more |
ブーリアン |
|
The HTTP policy that this permission set is linked to. There are three built-in policies: permit, deny and authenticated. Role based policies can be defined, and extensions can add their own policies. Environment variable: Show more |
string |
required |
The methods that this permission set applies to. If this is not set then they apply to all methods. Note that if a request matches any path from any permission set, but does not match the constraint due to the method not being listed then the request will be denied. Method specific permissions take precedence over matches that do not have any methods set. This means that for example if Quarkus is configured to allow GET and POST requests to /admin to and no other permissions are configured PUT requests to /admin will be denied. Environment variable: Show more |
文字列のリスト |
|
The paths that this permission check applies to. If the path ends in /* then this is treated as a path prefix, otherwise it is treated as an exact match. Matches are done on a length basis, so the most specific path match takes precedence. If multiple permission sets match the same path then explicit methods matches take precedence over matches without methods set, otherwise the most restrictive permissions are applied. Environment variable: Show more |
文字列のリスト |
|
One or more path specific authentication mechanisms separated by comma. Every listed value needs to match Environment variable: Show more |
文字列のリスト |
|
Indicates that this policy always applies to the matched paths in addition to the policy with a winning path. Avoid creating more than one shared policy to minimize the performance impact. Environment variable: Show more |
ブーリアン |
|
Whether permission check should be applied on all matching paths, or paths specific for the Jakarta REST resources. Environment variable: Show more |
|
|
The roles that are allowed to access resources protected by this policy. By default, access is allowed to any authenticated user. Environment variable: Show more |
文字列のリスト |
|
Add roles granted to the Environment variable: Show more |
Map<String,List<String>> |
|
Permissions granted to the Environment variable: Show more |
Map<String,List<String>> |
|
Permissions granted by this policy will be created with a Environment variable: Show more |
string |
|
Map the For example, if Environment variable: Show more |
Map<String,List<String>> |
|
Client certificate attribute whose values are going to be mapped to the 'SecurityIdentity' roles according to the roles mapping specified in the certificate properties file. The attribute must be either one of the Relative Distinguished Names (RDNs) or Subject Alternative Names (SANs). By default, the Common Name (CN) attribute value is used for roles mapping. Supported values are:
Environment variable: Show more |
string |
|
Properties file containing the client certificate attribute value to role mappings. Use it only if the mTLS authentication mechanism is enabled with either Properties file is expected to have the Environment variable: Show more |
path |
|
The authentication realm Environment variable: Show more |
string |
|
The login page. Redirect to login page can be disabled by setting Environment variable: Show more |
string |
|
List of query parameters that should be passed through when Quarkus redirects requests to the login page. For example, if a request to the Environment variable: Show more |
文字列のリスト |
|
The username field name. Environment variable: Show more |
string |
|
The password field name. Environment variable: Show more |
string |
|
The error page. Redirect to error page can be disabled by setting Environment variable: Show more |
string |
|
List of query parameters that should be passed through when Quarkus redirects requests to the error page. For example, if the POST request to the Environment variable: Show more |
文字列のリスト |
|
The landing page to redirect to if there is no saved page to redirect back to. Redirect to landing page can be disabled by setting Environment variable: Show more |
string |
|
List of query parameters that should be passed through when Quarkus redirects requests to the landing page. For example, if the POST request to the Environment variable: Show more |
文字列のリスト |
|
Option to control the name of the cookie used to redirect the user back to the location they want to access. Environment variable: Show more |
string |
|
The inactivity (idle) timeout When inactivity timeout is reached, cookie is not renewed and a new login is enforced. Environment variable: Show more |
|
|
How old a cookie can get before it will be replaced with a new cookie with an updated timeout, also referred to as "renewal-timeout". Note that smaller values will result in slightly more server load (as new encrypted cookies will be generated more often); however, larger values affect the inactivity timeout because the timeout is set when a cookie is generated. For example if this is set to 10 minutes, and the inactivity timeout is 30m, if a user’s last request is when the cookie is 9m old then the actual timeout will happen 21m after the last request because the timeout is only refreshed when a new cookie is generated. That is, no timeout is tracked on the server side; the timestamp is encoded and encrypted in the cookie itself, and it is decrypted and parsed with each request. Environment variable: Show more |
|
|
The cookie that is used to store the persistent session Environment variable: Show more |
string |
|
The cookie path for the session and location cookies. Environment variable: Show more |
string |
|
Cookie domain parameter value which, if set, will be used for the session and location cookies. Environment variable: Show more |
string |
|
Set the HttpOnly attribute to prevent access to the cookie via JavaScript. Environment variable: Show more |
ブーリアン |
|
SameSite attribute for the session and location cookies. Environment variable: Show more |
|
|
Max-Age attribute for the session cookie. This is the amount of time the browser will keep the cookie. The default value is empty, which means the cookie will be kept until the browser is closed. Environment variable: Show more |
||
The post location. Environment variable: Show more |
string |
|
Form-based authentication mechanism priority. Environment variable: Show more |
int |
|
Require that all registered HTTP authentication mechanisms must attempt to verify the request credentials. By default, when the All produced security identities can be retrieved using the following utility method:
An injected This property is false by default which means that the authentication process is complete as soon as the first This property will be ignored if the path specific authentication is enabled. Environment variable: Show more |
ブーリアン |
|
Inclusive authentication mode. Environment variable: Show more |
|
|
Mutual TLS authentication mechanism priority. Environment variable: Show more |
int |
|
Basic authentication mechanism priority. Environment variable: Show more |
int |
|
|
期間フォーマットについて
期間の値を書くには、標準の 数字で始まる簡略化した書式を使うこともできます:
その他の場合は、簡略化されたフォーマットが解析のために
|
フォームベース認証をプログラムで設定する
フォームベース認証の設定リファレンス セクションに記載されている設定プロパティーに加えて、Quarkus は以下の例のように実行時にプログラムによる設定をサポートします。
package org.acme.http.security;
import io.quarkus.vertx.http.security.Form;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;
public class FormConfiguration {
void configure(@Observes HttpSecurity httpSecurity) { (1)
httpSecurity.mechanism(Form.builder()
.httpOnlyCookie()
.loginPage("/my-login.html")
.errorPage("/my-error.html")
.build());
}
}
| 1 | io.quarkus.vertx.http.security.HttpSecurity CDI イベントを監視し、Form 認証メカニズムをプログラムで設定します。 |
相互TLS認証
Quarkus は相互 TLS (mTLS) 認証を提供しており、X.509 証明書に基づいてユーザーを認証できます。
この認証方法を使用するには、まずアプリケーションで SSL/TLS を有効にする必要があります。詳細については、Quarkus の「HTTP リファレンス」ガイドの Supporting secure connections with SSL/TLS セクションを参照してください。
アプリケーションがセキュアな接続を受け入れたら、次のステップは、アプリケーションが信頼するすべての証明書を保持するファイルの名前を使用して quarkus.http.ssl.certificate.trust-store-file 設定プロパティーを設定することです。このファイルには、ブラウザーやその他のサービスなどのクライアントが保護されたリソースの 1 つにアクセスしようとしたときに、アプリケーションが証明書を要求する方法に関する情報も含まれます。
JKS は Quarkus のデフォルトのキーストアおよびトラストストア形式ではなくなったため、フレームワークはファイル拡張子に基づいて推測を行います。
-
.pem、.crt、および.keyは PEM 証明書および鍵として読み取られます。 -
.jks、.keystore、および.truststoreは、JKS キーストアおよびトラストストアとして読み取られます。 -
.p12、.pkcs12、および.pfxは PKCS12 キーストアおよびトラストストアとして読み取られます。
ファイルでこれらの拡張子が使用されていない場合は、次のプロパティーを使用して形式を設定する必要があります。
quarkus.http.ssl.certificate.key-store-file-type=JKS # or P12 or PEM
quarkus.http.ssl.certificate.trust-store-file-type=JKS # or P12 or PEM
JKS は、あまり一般的に使用されなくなっています。Java 9 以降、Java のデフォルトのキーストア形式は PKCS12 です。JKS と PKCS12 の最も大きな違いは、JKS が Java 固有のフォーマットであることです。対照的に、PKCS12 は、暗号化された秘密鍵と証明書を保存するための標準化された言語中立的な方法です。
mTLS を有効にするための設定例を次に示します。
quarkus.http.ssl.certificate.key-store-file=server-keystore.jks (1)
quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks (2)
quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required (3)
quarkus.http.auth.permission.default.paths=/* (4)
quarkus.http.auth.permission.default.policy=authenticated
quarkus.http.insecure-requests=disabled (5)
| 1 | サーバーの秘密鍵が置かれているキーストア。 |
| 2 | 信頼された証明書がロードされるトラストストア。 |
| 3 | quarkus.http.ssl.client-auth を required に設定すると、サーバーがクライアント証明書を要求します。サーバーが証明書なしでリクエストを受け入れる必要がある場合は、これを REQUEST に設定できます。この設定は、mTLS 以外の複数の認証方法をサポートする場合に便利です。 |
| 4 | 認証されたユーザーのみがアプリケーションのリソースにアクセスできるようにするポリシーを定義します。 |
| 5 | プレーン HTTP プロトコルを無効にし、すべてのリクエストで HTTPS を使用するように要求します。 quarkus.http.ssl.client-auth を required に設定すると、 quarkus.http.insecure-requests が自動的に無効になります。 |
受信リクエストがトラストストア内の有効な証明書と一致する場合、アプリケーションは次のように SecurityIdentity を注入することでサブジェクトを取得できます。
@Inject
SecurityIdentity identity;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return String.format("Hello, %s", identity.getPrincipal().getName());
}
次の例に示すコードを使用して証明書を取得することもできます。
import java.security.cert.X509Certificate;
import io.quarkus.security.credential.CertificateCredential;
CertificateCredential credential = identity.getCredential(CertificateCredential.class);
X509Certificate certificate = credential.getCertificate();
証明書属性をロールにマッピングする
クライアント証明書の情報を使用して、Quarkus SecurityIdentity にロールを追加できます。
クライアント証明書のコモンネーム (CN) 属性を確認した後、 SecurityIdentity に新しいロールを追加できます。新しいロールを追加する最も簡単な方法は、証明書属性をロールにマッピングする機能を使用することです。
たとえば、以下のように 相互TLS認証 を紹介するセクションで表示されるプロパティーを更新できます。
quarkus.http.ssl.certificate.key-store-file=server-keystore.jks
quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks
quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required
quarkus.http.insecure-requests=disabled
quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties (1)
quarkus.http.auth.permission.certauthenticated.paths=/* (2)
quarkus.http.auth.permission.certauthenticated.policy=role-policy-cert (2)
quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin (2)
| 1 | cert-role-mappings.properties クラスパスリソースには、 CN=role または CN=role1,role2 などの形式で、ロールへの証明書の CN 値のマップが含まれています。ここで、 alice=user,admin、 bob=user、および jdoe=tester の 3 つのエントリーが含まれていると仮定します。 |
| 2 | HTTP セキュリティーポリシーを使用して、リクエストを認可するには SecurityIdentity に user または admin ロールが必要であることを要求します。 |
上記の設定では、クライアント証明書の CN 属性が alice または bob の場合にリクエストが承認され、 jdoe の場合はリクエストが拒否されます。
証明書属性を使用して SecurityIdentity を強化する
自動の 証明書属性をロールにマッピングする オプションが適切でない場合は、いつでも SecurityIdentityAugmentor を登録できます。カスタム SecurityIdentityAugmentor は、さまざまなクライアント証明書属性の値をチェックし、それに応じて SecurityIdentity を強化できます。
SecurityIdentity のカスタマイズの詳細は、Quarkus 「Security のヒントとコツ」ガイドの セキュリティーアイデンティティーのカスタマイズ セクションを参照してください。
相互 TLS クライアント認証をプログラムで設定します。
相互TLS認証 セクションでは、次のように application.properties ファイルで相互 TLS クライアント認証を設定しました。
quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.p12
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
quarkus.http.ssl.client-auth=required (1)
quarkus.http.tls-configuration-name=tls-config-1 (2)
| 1 | 相互 TLS クライアント認証を有効にして、必須にします。 |
| 2 | HTTP サーバー TLS 通信には、tls-config-1 TLS 設定を使用します。 |
io.quarkus.vertx.http.security.HttpSecurity CDI イベントにより、以下の例のように相互 TLS 認証をプログラムで設定できます。
package org.acme.http.security;
import io.quarkus.tls.BaseTlsConfiguration;
import io.vertx.core.net.KeyCertOptions;
import io.vertx.core.net.KeyStoreOptions;
import io.vertx.core.net.SSLOptions;
import io.vertx.core.net.TrustOptions;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class MyTlsConfiguration extends BaseTlsConfiguration {
@Override
public KeyCertOptions getKeyStoreOptions() {
return new KeyStoreOptions()
.setPath("/tmp/certs/server-keystore.p12")
.setPassword("the_key_store_secret")
.setType("PKCS12");
}
@Override
public TrustOptions getTrustStoreOptions() {
return new KeyStoreOptions()
.setPath("/tmp/certs/server-truststore.jks")
.setPassword("the_trust_store_secret")
.setType("PKCS12");
}
@Override
public SSLOptions getSSLOptions() {
SSLOptions options = new SSLOptions();
options.setKeyCertOptions(getKeyStoreOptions());
options.setTrustOptions(getTrustStoreOptions());
options.setSslHandshakeTimeoutUnit(TimeUnit.SECONDS);
options.setSslHandshakeTimeout(10);
options.setEnabledSecureTransportProtocols(Set.of("TLSv1.3", "TLSv1.2"));
return options;
}
}
package org.acme.http.security;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;
public class MutualTlsClientAuthConfig {
void configure(@Observes HttpSecurity httpSecurity) {
httpSecurity.mTLS("tls-config-1", new MyTlsConfiguration()); (1)
}
}
| 1 | 相互 TLS クライアント認証を有効にして必須にし、HTTP サーバー TLS 通信には tls-config-1 TLS 設定を使用します。tls-config-1 TLS 設定は TLS レジストリーに登録されています。 |
証明書属性をロールにマッピングすることも可能です。証明書属性をロールにマッピングする セクションで説明されている例を考えてみましょう。
quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.p12
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
quarkus.http.ssl.client-auth=required
quarkus.http.tls-configuration-name=tls-config-1
quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties
プログラムによるセットアップでの設定は次のようになります。
package org.acme.http.security;
import io.quarkus.vertx.http.security.MTLS;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;
public class MutualTlsClientAuthConfig {
void configure(@Observes HttpSecurity httpSecurity) {
httpSecurity.mTLS(MTLS.builder()
.tls("tls-config-1", new MyTlsConfiguration())
.rolesMapping("CN-value", "user", "admin")
.build());
}
}
この API を使用すると、証明書を使用して SecurityIdentity を強化することもできます。
quarkus.http.tls-configuration-name=tls-config-1
quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.jks
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
package org.acme.http.security;
import io.quarkus.vertx.http.security.HttpSecurity;
import io.quarkus.vertx.http.security.MTLS;
import jakarta.enterprise.event.Observes;
import java.util.Set;
public class MutualTlsClientAuthConfig {
void configure(@Observes HttpSecurity httpSecurity) {
httpSecurity.mTLS(MTLS.builder()
.certificateToRolesMapper(x509Certificate -> { (1)
final Set<String> securityIdentityRoles;
// replace this logic with your own certificate to roles mapping
if (x509Certificate.getIssuerX500Principal() != null
&& "CN=quarkus.io".equals(x509Certificate.getIssuerX500Principal().getName())) {
securityIdentityRoles = Set.of("admin");
} else {
securityIdentityRoles = Set.of();
}
return securityIdentityRoles;
})
.build());
}
}
| 1 | 証明書属性を使用して SecurityIdentity を強化する セクションで、SecurityIdentityAugmentor を使用してクライアント証明書属性値を SecurityIdentity ロールにマッピングできることを述べました。MTLS API を使用すると、そのようなロールマッピングも定義できます。 |
Quarkus が起動に失敗した後、開発モードで HTTP サーバーを起動した場合、Quarkus は application.properties ファイルで提供されている設定にフォールバックする必要がある場合があります。これは既知の制限です。
|
その他のサポートされる認証メカニズム
Quarkus Security は、エクステンションによって、以下の認証メカニズムもサポートしています。
WebAuthn 認証
WebAuthn はパスワードに代わる認証メカニズムです。 新規ユーザーの登録やログインを行うサービスを作成する場合、パスワードの入力を求める代わりに、パスワードを置き換える WebAuthn を使用できます。 詳細については、 WebAuthn 認証メカニズムを使用した Quarkus アプリケーションの保護 ガイドを参照してください。
OpenID Connect 認証
OpenID Connect (OIDC) は、OAuth 2.0 プロトコル上で動作する ID レイヤーです。 OIDC により、クライアントアプリケーションは OIDC プロバイダーによって実行された認証に基づいてユーザーの身元を確認し、そのユーザーに関する基本情報を取得することができます。
Quarkus の quarkus-oidc エクステンションは、ベアラートークンと認可コードフロー認証メカニズムをサポートする、リアクティブで相互運用可能なマルチテナント対応 OIDC アダプターを提供します。
ベアラートークン認証メカニズムは、HTTP Authorization ヘッダーからトークンを抽出します。
認可コードフローメカニズムは、ユーザーを OIDC プロバイダーにリダイレクトして、ユーザーのアイデンティティーを認証します。 ユーザーが Quarkus にリダイレクトされた後、このメカニズムは、ID、アクセス、およびリフレッシュトークンに対して付与された提供コードを交換することで認証プロセスを完了します。
リフレッシュ可能な JSON Web Key (JWK) セットを使用して ID およびアクセス JSON Web Token (JWT) トークンを検証したり、リモートでそれらをイントロスペクトしたりできます。 ただし、バイナリートークンとしても知られる不透明なトークンは、リモートでのみイントロスペクトできます。
|
Quarkus OIDC エクステンションを使用すると、ベアラートークンと認可コードフロー認証メカニズムの両方が SmallRye JWT 認証 を使用して、JWT トークンを MicroProfile JWT |
OIDC 認証のための追加の Quarkus リソース
Quarkus アプリケーションの安全性を確保するために使用できる OIDC 認証および認可方法の詳細については、以下のリソースを参照してください。
| OIDC トピック | Quarkus 情報リソース |
|---|---|
ベアラートークン認証メカニズム |
|
認可コードフロー認証メカニズム |
|
OIDC と SAML アイデンティティーブローカー |
|
ベアラートークン認証または認可コードフローメカニズムをサポートできる複数のテナント |
|
一般的に使用される OpenID Connect プロバイダーを使用した Quarkus の保護 |
|
Keycloak を使用した認可の一元化 |
|
Keycloak のプログラムによる設定 |
|
実行時に Quarkus OIDC エクステンションを有効にするには、ビルド時に マルチテナント OIDC デプロイメントにおける個々のテナント設定の管理に関する詳細については、「OpenID Connect (OIDC) マルチテナンシーの使用」ガイドの テナント設定の無効化 セクションを参照してください。 |
OpenID Connect クライアントとフィルター
quarkus-oidc-client エクステンションは、以下のトークングラントをサポートする OpenID Connect および OAuth2 プロバイダーからアクセストークンを取得およびリフレッシュするための OidcClient を提供します。
-
client-credentials -
password -
refresh_token
quarkus-resteasy-client-oidc-filter エクステンションには quarkus-oidc-client エクステンションが必要です。
これは、 OidcClient によって取得されたアクセストークンを HTTP Authorization ヘッダーの Bearer スキーム値として設定する JAX-RS RESTful Web サービス OidcClientRequestFilter を提供します。
このフィルターは、現在の Quarkus エンドポイントに注入された MicroProfile REST クライアント実装に登録できますが、このサービスエンドポイントの認証要件とは関係ありません。
たとえば、パブリックエンドポイントにしたり、mTLS で保護したりできます。
|
このシナリオでは、Quarkus OpenID Connect アダプターを使用して Quarkus エンドポイントを保護する必要はありません。 |
quarkus-resteasy-client-oidc-token-propagation エクステンションには quarkus-oidc エクステンションが必要です。
これは、OpenID Connect ベアラートークンまたは認可コードフローアクセストークンを HTTP Authorization ヘッダーの Bearer スキーム値として設定する Jakarta REST TokenCredentialRequestFilter を提供します。
このフィルターは、現在の Quarkus エンドポイントに注入された MicroProfile REST クライアント実装に登録できます。これは、Quarkus OIDC アダプターを使用して保護する必要があります。
このフィルターは、アクセストークンをダウンストリームサービスに伝播できます。
詳細については、 OpenID Connect クライアントとトークン伝播クイックスタート および OpenID Connect (OIDC) と OAuth2 クライアントとフィルターのリファレンス ガイドを参照してください。
SmallRye JWT 認証
quarkus-smallrye-jwt エクステンションは、MicroProfile JSON Web Token (JWT) 2.1 実装と、署名および暗号化された JWT トークンを検証する複数のオプションを提供します。
これらは org.eclipse.microprofile.jwt.JsonWebToken として表されます。
quarkus-smallrye-jwt は quarkus-oidc ベアラートークン認証メカニズムの代替であり、Privacy Enhanced Mail (PEM) キーまたはリフレッシュ可能な JWK キーセットのいずれかを使用して JWT トークンのみを検証します。
quarkus-smallrye-jwt は JWT 生成 API も提供しており、これを使用して signed、 inner-signed、および encrypted の JWT トークンを簡単に作成できます。
詳細については、 JWT RBAC の使用 ガイドを参照してください。
OAuth2 認証
quarkus-elytron-security-oauth2 は、Quarkus quarkus-oidc ベアラートークン認証メカニズムエクステンションに対する代替を提供します。
quarkus-elytron-security-oauth2 は Elytron に基づいており、主に不透明トークンをリモートでイントロスペクトすることを目的としています。
詳細については、Quarkus の OAuth2 の使用 ガイドを参照してください。
OpenID Connect、SmallRye JWT、および OAuth2 認証メカニズムからの選択
次の情報を使用して、Quarkus アプリケーションを保護するための適切なトークン認証メカニズムを選択してください。
-
quarkus-oidcには、ベアラートークンを検証したり、認可コードフローでエンドユーザーを認証したりできる Keycloak などの OpenID Connect プロバイダーが必要です。 どちらの場合も、quarkus-oidcは指定された OpenID Connect プロバイダーへの接続を必要とします。 -
ユーザー認証に認可コードフローが必要な場合、または複数のテナントをサポートする必要がある場合は、
quarkus-oidcを使用してください。quarkus-oidcは、認可コードフローとベアラーアクセストークンの両方を使用して、ユーザー情報を要求することもできます。 -
ベアラートークンを検証する必要がある場合は、
quarkus-oidc、quarkus-elytron-security-oauth2、またはquarkus-smallrye-jwtを使用してください。 -
ベアラー トークンが JSON Web トークン (JWT) 形式である場合は、上記のリストにある任意のエクステンションを使用できます。
quarkus-oidcとquarkus-smallrye-jwtはどちらも、OpenID Connect プロバイダーがキーをローテーションするときにJsonWebKey(JWK) セットを更新することをサポートしています。したがって、リモートトークンイントロスペクションを回避する必要がある場合や、プロバイダーがサポートしていない場合は、JWT トークンを検証するためにquarkus-oidcまたはquarkus-smallrye-jwtを使用してください。 -
JWT トークンをリモートでイントロスペクトするには、
quarkus-oidcまたはquarkus-elytron-security-oauth2を使用して、リモートイントロスペクションによって不透明またはバイナリー トークンを検証できます。quarkus-smallrye-jwtは、不透明トークンと JWT トークンの両方のリモートイントロスペクションをサポートしておらず、代わりに通常 OpenID Connect プロバイダーから取得されるローカルで利用可能なキーに依存します。 -
quarkus-oidcとquarkus-smallrye-jwtは、JWT および不透明トークンをエンドポイントコードに注入することをサポートしています。注入された JWT トークンは、ユーザーに関するより多くの情報を提供します。すべてのエクステンションは、トークンをPrincipalとして注入できます。 -
quarkus-smallrye-jwtはquarkus-oidcよりも多くのキーフォーマットをサポートしています。quarkus-oidcは JWK セットの一部である JWK 形式のキーのみを使用しますが、quarkus-smallrye-jwtは PEM キーをサポートしています。 -
quarkus-smallrye-jwtは、ローカルで署名されたトークン、内部で署名され暗号化されたトークン、および暗号化されたトークンを処理します。対照的に、quarkus-oidcとquarkus-elytron-security-oauth2もそのようなトークンを検証できますが、それらを不透明トークンとして扱い、リモートイントロスペクションを通じて検証します。 -
不透明トークンまたは JWT トークンのリモートイントロスペクションのための軽量ライブラリーが必要な場合は、
quarkus-elytron-security-oauth2を使用してください。
|
不透明トークンまたは JSON Web トークン (JWT) 形式のどちらを使用するかは、アーキチャーの考慮事項に基づいて決定されます。不透明トークンは JWT トークンよりもはるかに短い傾向がありますが、トークンに関連する状態のほとんどをプロバイダーデータベースで維持する必要があります。不透明トークンは事実上データベースポインターです。 JWT トークンは不透明トークンよりも大幅に長くなります。それでも、プロバイダーは、トークンクレームとしてトークン関連の状態を保存し、署名または暗号化することで、その状態のほとんどをクライアントに効果的に委譲します。 |
| 必要な機能 | 認証メカニズム | ||
|---|---|---|---|
|
|
|
|
ベアラー JWT の検証 |
ローカル検証またはイントロスペクション |
ローカル検証 |
イントロスペクション |
ベアラー不透明トークンの検証 |
イントロスペクション |
いいえ |
イントロスペクション |
JWT トークンを検証するための |
はい |
はい |
いいえ |
トークンを |
はい |
はい |
はい |
JWT を MP JWT としてインジェクト |
はい |
はい |
いいえ |
認可コードフロー |
はい |
いいえ |
いいえ |
マルチテナンシー |
はい |
いいえ |
いいえ |
ユーザー情報サポート |
はい |
いいえ |
いいえ |
PEM キーフォーマットのサポート |
いいえ |
はい |
いいえ |
SecretKey のサポート |
いいえ |
JSON Web Key (JWK) 形式で |
いいえ |
内部署名され暗号化されたトークン、または暗号化されたトークン |
イントロスペクション |
ローカル検証 |
イントロスペクション |
カスタムトークンの検証 |
いいえ |
注入された JWT パーサーを使用 |
いいえ |
Cookie としての JWT サポート |
いいえ |
はい |
はい |
認証メカニズムの組み合わせ
異なるソースがユーザークレデンシャルを提供する場合、認証メカニズムを組み合わせることができます。たとえば、組み込みの Basic 認証メカニズムと Quarkus の quarkus-oidc ベアラー トークン認証メカニズムを組み合わせることができます。
認証メカニズムのいずれかによって最初の SecurityIdentity が生成されるとすぐに、認証プロセスが完了します。
認証メカニズムの優先度
Quarkus Security は、どのメカニズムが最初に SecurityIdentity を生成する機会を得るかを決定するために、優先度システムを使用します。認証メカニズムの優先度は、次の順序に影響します。
-
クレデンシャル検証: 優先度の高いメカニズムが最初にクレデンシャルを検証するように求められます。最初にクレデンシャルを検証したものが優先されます。
-
認証チャレンジ: リクエストが認証されていない場合、優先度の高いメカニズムが最初にチャレンジを発行するように求められます。
デフォルトの優先度は、以下にリストされている設定プロパティーを使用して上書きできます。
| 認証メカニズム^ | 設定プロパティー^ | デフォルトの優先度 |
|---|---|---|
Basic 認証メカニズム |
|
2000 |
フォームベース認証メカニズム |
|
1000 |
相互 TLS 認証メカニズム |
|
デフォルトで 1000、統合認証が有効な場合は 3000 |
WebAuthn 認証メカニズム |
|
1000 |
OIDC 認証メカニズム |
|
1001 |
SmallRye JWT 認証メカニズム |
|
1000 |
統合認証
場合によっては、登録されているすべての認証メカニズムが SecurityIdentity を作成することが必要になることがあります。これは、トークンなどの認証情報を 相互TLS認証 経由で渡す必要がある場合に必要になることがあります。たとえば、ユーザーが Virtual Private Network 経由で認証している場合や、トークンの検証を成功させるために現在のトークンをクライアント証明書にバインドして、このトークンをクライアント証明書とともに Quarkus に渡している同じクライアントにトークンが正確に発行されたことを保証する場合などです。
Quarkus では、このような認証は inclusive (統合認証) と呼ばれ、次のようにして有効にできます:
quarkus.http.auth.inclusive=true
認証が統合認証である場合、最初の認証メカニズムによって作成された SecurityIdentity はアプリケーションコードに挿入されます。たとえば、相互TLS認証 と基本的な認証メカニズムの認証の両方が必要な場合、相互TLS認証 メカニズムが最初に SecurityIdentity を作成します。
|
統合認証が有効な場合、相互TLS認証 メカニズムはデフォルトで最高の優先度を持ちます。これは、使用時にトランスポートレベルで早期に適用されるという事実を反映し、挿入された |
追加の SecurityIdentity インスタンスには、最初の SecurityIdentity の quarkus.security.identities 属性としてアクセスできます。しかし、これらの追加のアイデンティティーに直接アクセスする必要がない場合があります。たとえば、相互TLS認証 と OIDC ベアラー認証 メカニズムの両方が組み合わされて認証が行われている場合、認証されたベアラートークンは、相互TLS認証 によって作成された SecurityIdentity とともにトークン認証情報として注入できます。以下に例を示します:
package org.acme.security;
import io.quarkus.oidc.AccessTokenCredential;
import io.quarkus.oidc.common.runtime.OidcConstants;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.HttpSecurityUtils;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class InclusiveAuthExampleBean {
@Inject
SecurityIdentity mtlsIdentity; (1)
@Inject
AccessTokenCredential accessTokenCredential;
private AccessTokenCredential getAccessTokenCredential() {
if (doItHardWay()) {
var securityIdentities = HttpSecurityUtils.getSecurityIdentities(mtlsIdentity); (2)
if (securityIdentities != null) {
SecurityIdentity bearerIdentity = securityIdentities.get(OidcConstants.BEARER_SCHEME);
if (bearerIdentity != null) {
return bearerIdentity.getCredential(AccessTokenCredential.class);
}
}
}
return accessTokenCredential;
}
}
| 1 | これは、該当する認証メカニズムによって作成された、最高の優先度を持つ SecurityIdentity です。 |
| 2 | その他の該当する認証メカニズムは認証を実行し、 SecurityIdentity で利用できます。 |
|
Quarkus の |
複数のアイデンティティーによる認可
認可は常に、最初に生成された SecurityIdentity に対して実行されます。たとえば:
package org.acme.security;
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
class DataService {
@RolesAllowed("admin") (1)
void deleteEntity(Long entityId) {
// business logic
}
}
| 1 | deleteEntity メソッドには、最初の SecurityIdentity が admin ロールを持つ場合にのみアクセスできます。最初の SecurityIdentity を生成するためにどの認証メカニズムが使用されるかに影響を与えるには、メカニズムの優先度を設定 してください。 |
すべての SecurityIdentity インスタンスに対して認可を実行したい場合は、手動で行う必要があります。たとえば、いずれかのアイデンティティーによってパーミッションが許可されているかどうかを確認するには、@PermissionChecker アノテーションを使用します:
package org.acme.security;
import io.quarkus.security.PermissionChecker;
import io.quarkus.security.PermissionsAllowed;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.HttpSecurityUtils;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
class DataService {
@PermissionsAllowed("canDeleteEntity")
void deleteEntity(Long entityId) {
// business logic
}
@PermissionChecker("canDeleteEntity")
boolean canDeleteEntity(SecurityIdentity firstIdentity) {
var allSecurityIdentities = HttpSecurityUtils.getSecurityIdentities(firstIdentity);
if (allSecurityIdentities != null) {
for (SecurityIdentity identity : allSecurityIdentities.values()) {
if (identity.hasRole("admin")) {
return true;
}
}
}
return false;
}
}
パスベース認証
HTTP セキュリティーポリシーを使用してパスベース認証を有効にする
次の設定例は、あるリクエストパスに対して、選択可能な単一の認証メカニズムを強制する方法を示しています:
quarkus.http.auth.permission.basic.paths=/hello/basic (1)
quarkus.http.auth.permission.basic.policy=authenticated
quarkus.http.auth.permission.basic.auth-mechanism=basic
quarkus.http.auth.permission.bearer.paths=/hello/bearer (2)
quarkus.http.auth.permission.bearer.policy=authenticated
quarkus.http.auth.permission.bearer.auth-mechanism=bearer
quarkus.http.auth.permission.custom.paths=/hello/custom (3)
quarkus.http.auth.permission.custom.policy=authenticated
quarkus.http.auth.permission.custom.auth-mechanism=custom
quarkus.http.auth.permission.basic-bearer.paths=/hello/basic-bearer (4)
quarkus.http.auth.permission.basic-bearer.policy=authenticated
quarkus.http.auth.permission.basic-bearer.auth-mechanism=basic,bearer
| 1 | REST エンドポイント /hello/basic には、Basic 認証 を使用する場合のみアクセスできます。 |
| 2 | REST エンドポイント /hello/bearer には、OIDC ベアラー認証メカニズム を使用する場合のみアクセスできます。 |
| 3 | REST エンドポイント /hello/custom には、custom 認証スキームを持つカスタム HttpAuthenticationMechanism を使用する場合のみアクセスできます。 |
| 4 | REST エンドポイント /hello/basic-bearer には、OIDC ベアラー認証メカニズム または Basic 認証 のいずれかを使用してアクセスできます。 |
|
|
HTTP セキュリティーポリシーの統合パスベース認証を使用する
統合認証 が strict モードで有効な場合、選択されたすべての認証メカニズムが SecurityIdentity を提供する必要があります。たとえば:
quarkus.http.auth.inclusive=true
quarkus.http.auth.permission.basic-bearer.paths=/hello/basic-bearer
quarkus.http.auth.permission.basic-bearer.policy=authenticated
quarkus.http.auth.permission.basic-bearer.auth-mechanism=basic,bearer (1)
| 1 | REST エンドポイント /hello/basic-bearer には、OIDC ベアラー認証メカニズム と Basic 認証 の両方が SecurityIdentity を正常に提供した場合にのみアクセスできます。 |
統合認証 が lax モードで有効な場合、選択されたすべての認証メカニズムは独自の SecurityIdentity を提供する機会を得ますが、少なくとも 1 つのメカニズムが SecurityIdentity を生成することが期待されます。次の例を考慮してください:
quarkus.http.auth.inclusive=true
quarkus.http.auth.inclusive-mode=lax
quarkus.http.auth.permission.basic-bearer.paths=/hello/basic-bearer
quarkus.http.auth.permission.basic-bearer.policy=authenticated
quarkus.http.auth.permission.basic-bearer.auth-mechanism=basic,bearer (1)
| 1 | REST エンドポイント /hello/basic-bearer は、OIDC ベアラー認証メカニズム と Basic 認証 の両方を使用します。いずれかが SecurityIdentity を正常に提供すればアクセスが許可されます。 |
アノテーションを使用して Jakarta REST エンドポイントのパスベース認証を有効にする
アノテーションを使用して、各 Jakarta REST エンドポイントに固有の認証メカニズムを選択できます。この機能は、REST エンドポイントが一致した後にのみ、認証メカニズムを選択するためにアノテーションを使用できることから、プロアクティブ認証 が無効化されている場合に限り、有効化されます。REST エンドポイントごとに認証メカニズムを選択する方法は次のとおりです。
quarkus.http.auth.proactive=false
import io.quarkus.oidc.AuthorizationCodeFlow;
import io.quarkus.vertx.http.runtime.security.annotation.BasicAuthentication;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@Path("hello")
public class HelloResource {
@GET
@BasicAuthentication (1) (2)
@Path("basic")
public String basicAuthMechanism() {
return "basic";
}
@GET
@RolesAllowed("admin") (3)
@AuthorizationCodeFlow (4)
@Path("code-flow")
public String codeFlowAuthMechanism() {
return "code-flow";
}
@GET
@HttpAuthenticationMechanism("custom") (5) (6)
@Path("custom")
public String customAuthMechanism() {
return "custom";
}
@GET
@BasicAuthentication
@AuthorizationCodeFlow
@Path("basic-or-code-flow")
public String basicOrCodeFlowAuthMechanism() { (7)
return "basic-or-code-flow";
}
}
| 1 | REST エンドポイント /hello/basic には、Basic 認証 を使用する場合のみアクセスできます。 |
| 2 | /hello/basic エンドポイントには認証が必要です。なぜなら、標準のセキュリティーアノテーションが @BasicAuthentication アノテーションに付随しない場合、デフォルトで @Authenticated アノテーションが追加されるためです。 |
| 3 | @AuthorizationCodeFlow アノテーションは、@RolesAllowed、@PermissionsAllowed などの他の標準セキュリティーアノテーションと組み合わせることができます。 |
| 4 | REST エンドポイント /hello/code-flow には、OIDC 認可コードフローメカニズム を使用する場合のみアクセスできます。 |
| 5 | REST エンドポイント /hello/custom には、custom 認証スキームを持つカスタム HttpAuthenticationMechanism を使用する場合のみアクセスできます。 |
| 6 | /hello/custom エンドポイントには認証が必要です。なぜなら、標準のセキュリティーアノテーションが @HttpAuthenticationMechanism アノテーションに付随しない場合、デフォルトで @Authenticated アノテーションが追加されるためです。 |
| 7 | REST エンドポイント /hello/basic-or-code-flow には、OIDC 認可コードフローメカニズム または Basic 認証 のいずれかを使用してアクセスできます。 |
|
|
| 認証メカニズム^ | アノテーション |
|---|---|
Basic 認証メカニズム |
|
フォームベース認証メカニズム |
|
相互 TLS 認証メカニズム |
|
WebAuthn 認証メカニズム |
|
ベアラートークン認証メカニズム |
|
OIDC 認可コードフローメカニズム |
|
SmallRye JWT 認証メカニズム |
|
Quarkus は、認証メカニズムアノテーションが付けられたエンドポイントを自動的に保護します。REST エンドポイントとリソースに標準のセキュリティーアノテーションが存在しない場合は、 io.quarkus.security.Authenticated アノテーションが追加されます。
|
また、 io.quarkus.vertx.http.runtime.security.annotation.HttpAuthenticationMechanism アノテーションを使用して、そのスキームに基づいて任意の認証メカニズムを選択することも可能です。quarkus.http.auth.permission.basic.auth-mechanism=custom 設定プロパティーに類似するアノテーションとして、 @HttpAuthenticationMechanism("custom") アノテーションがあります。
| さまざまな Jakarta EE 仕様との整合性を保つために、アノテーションの継承に依存するのではなく、常にアノテーションを繰り返すことが推奨されます。 |
アノテーションを使用して Jakarta REST エンドポイントの統合パスベース認証を有効にする
統合認証 が strict モードで有効な場合、選択されたすべての認証メカニズムが SecurityIdentity を提供する必要があります。たとえば:
quarkus.http.auth.inclusive=true
quarkus.http.auth.proactive=false
package org.acme.http.security;
import io.quarkus.oidc.AuthorizationCodeFlow;
import io.quarkus.vertx.http.runtime.security.annotation.BasicAuthentication;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@BasicAuthentication
@AuthorizationCodeFlow
@Path("hello")
public class HelloResource {
@GET
@Path("basic-and-code-flow")
public String basicAndCodeFlowAuthMechanism() { (1)
return "basic-and-code-flow";
}
}
| 1 | REST エンドポイント /hello/basic-and-code-flow は、OIDC 認可コードフローメカニズム と Basic 認証 の両方が SecurityIdentity を正常に提供した場合にのみアクセスできます。 |
統合認証 が lax モードで有効な場合、選択されたすべての認証メカニズムは独自の SecurityIdentity を提供する機会を得ますが、少なくとも 1 つのメカニズムが SecurityIdentity を生成することが期待されます。次の例を考慮してください:
quarkus.http.auth.inclusive=true
quarkus.http.auth.inclusive-mode=lax
quarkus.http.auth.proactive=false
package org.acme.http.security;
import io.quarkus.oidc.AuthorizationCodeFlow;
import io.quarkus.vertx.http.runtime.security.annotation.BasicAuthentication;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@BasicAuthentication
@AuthorizationCodeFlow
@Path("hello")
public class HelloResource {
@GET
@Path("basic-and-code-flow")
public String basicAndCodeFlowAuthMechanism() { (1)
return "basic-and-code-flow";
}
}
| 1 | REST エンドポイント /hello/basic-and-code-flow は、OIDC 認可コードフローメカニズム と Basic 認証 の両方を使用します。少なくともどちらか一方が SecurityIdentity を正常に提供した場合にアクセスが許可されます。 |
統合認証を使用してパスベース認証を有効にする
デフォルトでは、Quarkus は REST エンドポイントごとにアノテーションで選択された 1 つの認証メカニズムに対してのみ パスベース認証 をサポートします。パスベース認証 に複数の認証メカニズムを使用する必要がある場合は、「セキュリティに関するヒントとコツ」ガイドの 複数の HttpAuthenticationMechanism の処理 セクションに記載されているように、カスタムの HttpAuthenticationMechanism を記述できます。もう 1 つの方法は、lax モードで 統合認証 を有効にし、登録されているすべての HTTP 認証メカニズムがメカニズム固有の SecurityIdentity を作成したことを確認するカスタムの HttpSecurityPolicy または PermissionChecker を記述することです。
quarkus.http.auth.inclusive-mode=lax (1)
quarkus.http.auth.inclusive=true
| 1 | デフォルトでは、統合認証では、登録されているすべての HTTP 認証メカニズムが SecurityIdentity を作成する必要があります。ただし、lax モードでは、少なくとも 1 つの登録済み HttpAuthenticationMechanism が SecurityIdentity を作成すると、認証が成功します。 |
mTLS、Basic、OIDC の 3 つの登録済みメカニズムがあり、 hello メソッドへのアクセスを許可するのに Basic 認証と mTLS 認証のみが成功する必要があると仮定します。この場合、lax モードで統合認証を有効にすると、次の例に示すように、どのメカニズムがアイデンティティーを生成したかを確認できます。
import io.quarkus.security.PermissionChecker;
import io.quarkus.security.PermissionsAllowed;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.HttpSecurityUtils;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.util.Map;
@Path("/hello")
public class HelloResource {
@PermissionsAllowed("mtls-basic")
@GET
public String hello() {
return "Hello world";
}
@PermissionChecker("mtls-basic")
boolean isMtlsAndBasicAuthentication(SecurityIdentity identity) {
Map<String, SecurityIdentity> identities = HttpSecurityUtils.getSecurityIdentities(identity);
if (identities != null) {
return identities.containsKey("basic") && identities.containsKey("x509"); (1)
}
return false;
}
}
| 1 | mTLS と Basic の両方の認証メカニズムが現在のリクエストを認証したことが確認された場合にのみ、エンドポイントへのアクセスを許可します。 |
HTTP セキュリティーポリシーとの組み合わせ方法
個々のリソースにアクセスできるロールを定義する最も簡単な方法は、 @RolesAllowed アノテーションを使用することです。ただし、次の例のように HTTP セキュリティーポリシーを使用することもできます。
quarkus.http.auth.policy.roles1.roles-allowed=user
quarkus.http.auth.permission.roles1.paths=/hello/code-flow
quarkus.http.auth.permission.roles1.applies-to=JAXRS (1)
quarkus.http.auth.permission.roles1.policy=roles1
quarkus.http.auth.permission.roles1.methods=GET (2)
| 1 | エンドポイント固有の認証メカニズムが選択された後、このポリシーの権限チェックを遅らせます。 |
| 2 | roles1 権限が、 @AuthorizationCodeFlow アノテーションが付けられたエンドポイントのみと一致するようにします。アノテーションが付いていないエンドポイントは、 applies-to=JAXRS オプションによって発生する遅延を回避する必要があります。 |
プロアクティブ認証
Quarkus では、デフォルトでプロアクティブ認証が有効になっています。これは、受信リクエストにクレデンシャルがある場合、ターゲットページで認証が必要ない場合でも、リクエストは常に認証されることを意味します。詳細については、Quarkus の プロアクティブ認証 ガイドを参照してください。