2.2. ビルトイン認証メカニズム
Quarkus Security は、次のビルトイン認証サポートを提供します。
2.2.1. Basic 認証
ビルトイン HTTP Basic 認証メカニズムを使用して、Quarkus アプリケーションのエンドポイントを保護できます。詳細は、以下のドキュメントを参照してください。
2.2.2. フォームベース認証
Quarkus は、従来の Servlet フォームベース認証と同様に機能するフォームベース認証を提供します。従来のフォーム認証とは異なり、Quarkus はクラスター化された HTTP セッションをサポートしていないため、認証されたユーザーは HTTP セッションに保存されません。代わりに、認証情報が暗号化された Cookie に保存されます。同じ暗号鍵を共有するすべてのクラスターメンバーは、これを読み取ることができます。
暗号化を適用するには、quarkus.http.auth.session.encryption-key
プロパティーを追加し、設定する値が 16 文字以上であることを確認します。暗号鍵は、SHA-256 を使用してハッシュされます。結果のダイジェストは、Cookie 値の AES-256 暗号化の鍵として使用されます。Cookie には暗号化された値の一部として有効期限が含まれているため、クラスター内のすべてのノードのクロックを同期する必要があります。セッションが使用中の場合、更新された有効期限を持つ新しい Cookie が 1 分ごとに生成されます。
フォーム認証の使用を開始するには、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 を使用してこの情報を保存する必要があります。詳細は、Jakarta Persistence を備えた Quarkus Security または 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 を破棄します。
@ConfigProperty(name = "quarkus.http.auth.form.cookie-name") String cookieName; @Inject CurrentIdentityAssociation identity; @POST public Response logout() { if (identity.getIdentity().isAnonymous()) { throw new UnauthorizedException("Not authenticated"); } final NewCookie removeCookie = new NewCookie.Builder(cookieName) .maxAge(0) .expiry(Date.from(Instant.EPOCH)) .path("/") .build(); return Response.noContent().cookie(removeCookie).build(); }
フォームベース認証を設定するには、次のプロパティーを使用できます。
ビルド時に固定された設定プロパティー: その他の設定プロパティーはすべて実行時にオーバーライド可能
設定プロパティー | 型 | デフォルト |
権限セット全体を有効にするかどうかを決定します。デフォルトでは、権限セットが定義されている場合は有効になります。
環境変数: | boolean | |
この権限セットがリンクされている HTTP ポリシー。ビルトインポリシーには、permit、deny、authenticated の 3 つがあります。ロールベースのポリシーを定義でき、エクステンションは独自のポリシーを追加できます。
環境変数: | string | required |
この権限セットが適用されるメソッド。これが設定されていない場合は、すべてのメソッドに適用されます。リクエストが任意の権限セットからの任意のパスに一致し、そのメソッドがリストされていないために制約に一致しない場合、リクエストは拒否されることに注意してください。メソッド固有の権限は、メソッドが設定されていない一致よりも優先されます。たとえば、Quarkus が /admin への GET および POST リクエストを許可するように設定されていて、他の権限が設定されていない場合、/admin への PUT リクエストは拒否されます。
環境変数: | 文字列のリスト | |
この権限チェックが適用されるパス。パスが /* で終わる場合はパスの接頭辞として処理され、それ以外の場合は完全一致として処理されます。一致は長さに基づいて行われるため、パスに最も具体的に一致する場合が優先されます。複数の権限セットが同じパスに一致する場合、メソッドの明示的な一致がメソッドが設定されていない一致よりも優先され、それ以外の場合は最も制限の厳しい権限が適用されます。
環境変数: | 文字列のリスト | |
ユーザー認証に使用しなければならないパス固有の認証メカニズム。'basic'、'bearer'、'form' などの
環境変数: | string | |
このポリシーが、優先されるパスのポリシーに加え、一致したパスにも必ず適用されることを示しています。パフォーマンスへの影響を最小限に抑えるため、複数の共有ポリシーは作成しないでください。
環境変数: | boolean |
|
権限チェックをすべての一致するパスに適用するか、Jakarta REST リソースのパスにのみ適用するかを指定します。
環境変数: | all: すべての一致するパスに適用します。
jaxrs: 権限チェックを Jakarta REST リクエストパスにのみ適用する必要があることを宣言します。このオプションを使用すると、一致する Jakarta REST エンドポイントでアノテーションを使用して認証メカニズムを選択した場合の権限チェックを遅延できます。次の REST エンドポイントアノテーションを使用する場合は、このオプションを設定する必要があります。テナント識別子を持つ OIDC 認証メカニズムを選択する | all |
このポリシーによって保護されているリソースへのアクセスが許可されるロール。デフォルトでは、すべての認証済みユーザーにアクセスが許可されます。
環境変数: | 文字列のリスト |
|
環境変数: | Map<String,List<String>> | |
このポリシーが正常に適用され (ポリシーによりリクエストの続行が許可される)、認証されたリクエストに必要なロールがある場合に、
環境変数: | Map<String,List<String>> | |
このポリシーによって付与される権限は、この設定プロパティーによって指定された
環境変数: | string |
|
たとえば、
環境変数: | Map<String,List<String>> | |
証明書プロパティーファイルで指定されたロールマッピングに従って、値が 'SecurityIdentity' ロールにマッピングされるクライアント証明書属性。属性は、相対識別名 (RDN) またはサブジェクト代替名 (SAN) のいずれかである必要があります。デフォルトでは、コモンネーム (CN) 属性値がロールマッピングに使用されます。対応している値は次のとおりです。
環境変数: | string |
|
ロールマッピングへのクライアント証明書の属性値が含まれるプロパティーファイル。
プロパティーファイルは
環境変数: | path | |
認証レルム
環境変数: | string | |
ログインページ。
環境変数: | string |
|
ユーザー名のフィールド名。
環境変数: | string |
|
パスワードのフィールド名。
環境変数: | string |
|
エラーページ。
環境変数: | string |
|
リダイレクト先の保存済みページがない場合にリダイレクトするランディングページ。
環境変数: | string |
|
アクセスしたい場所にユーザーをリダイレクトするために使用される Cookie の名前を制御するオプション。
環境変数: | string |
|
非アクティブ (アイドル) タイムアウト。非アクティブタイムアウトに達すると、Cookie は更新されず、新たなログインが強制されます。
環境変数: |
| |
Cookie が、タイムアウトが更新された新しい Cookie に置き換えられるまでの Cookie 存続期間 ("renewal-timeout" とも呼ばれます)。値が小さいほど、サーバーの負荷がわずかに増加します (新しい暗号化された Cookie がより頻繁に生成されるため)。ただし、値が大きいと、Cookie の生成時にタイムアウトが設定されるため、非アクティブタイムアウトに影響します。たとえばこれが 10 分に設定され、非アクティブタイムアウトが 30 分に設定された場合、ユーザーの最終リクエストの Cookie 経過時間が 9 分と仮定すると、タイムアウトは新しい Cookie が生成された後でなければ更新されないため、実際のタイムアウトは最終リクエストの 21 分後に発生します。つまり、サーバー側ではタイムアウトは追跡されず、タイムスタンプは Cookie 自体にエンコードおよび暗号化され、リクエストごとに復号化されて解析されます。
環境変数: |
| |
永続的なセッションの保存に使用される Cookie。
環境変数: | string |
|
セッションクッキーとロケーション Cookie の Cookie パス。
環境変数: | string |
|
JavaScript 経由での Cookie へのアクセスを防ぐために、HttpOnly 属性を設定します。
環境変数: | boolean |
|
セッションおよびロケーションクッキーの SameSite 属性。
環境変数: |
|
|
duration の値を書き込むには、標準の java.time.Duration
フォーマットを使用します。詳細は、Duration#parse() Java API ドキュメント を参照してください。
数字で始まる簡略化されたフォーマットも使用できます。
- 値が数値のみの場合は、秒単位の時間を表します。
-
数字の後に
ms
が続く値は、ミリ秒単位の時間を表します。
その他の場合は、解析のために簡略化されたフォーマットが java.time.Duration
フォーマットに変換されます。
-
数字の後に
h
、m
、またはs
が続く値には、接頭辞PT
が付きます。 -
数字の後に
d
が続く値は、接頭辞P
が付きます。
2.2.3. 相互 TLS 認証
Quarkus は相互 TLS (mTLS) 認証を提供するため、X.509 証明書に基づきユーザーを認証できます。
この認証方法を使用するには、まずアプリケーションで SSL/TLS を有効にする必要があります。詳細は、Quarkus の「HTTP reference」ガイドの Supporting secure connections with SSL/TLS セクションを参照してください。
アプリケーションがセキュアな接続を受け入れた後、アプリケーションが信頼するすべての証明書を保持するファイルの名前を使用して quarkus.http.ssl.certificate.trust-store-file
プロパティーを設定します。このファイルには、ブラウザーや他のサービスなどのクライアントが保護されたリソースの 1 つにアクセスしようとしたときに、アプリケーションが証明書を要求する方法に関する情報も含まれています。
JKS は Quarkus のデフォルトのキーストアおよびトラストストア形式ではなくなったため、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();
2.2.3.1. 証明書属性をロールにマッピングする
クライアント証明書の情報を使用して、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 3 quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin 4
上記の設定では、クライアント証明書の CN 属性が alice
または bob
の場合にリクエストが認可され、jdoe
の場合はリクエストが拒否されます。
2.2.3.2. 証明書属性を使用して SecurityIdentity を強化する
自動で 証明書属性をロールにマッピングする オプションが適していない場合は、いつでも SecurityIdentityAugmentor
を登録できます。カスタム SecurityIdentityAugmentor
を使用して、さまざまなクライアント証明書属性の値を確認し、それに応じて SecurityIdentity
を拡張できます。
SecurityIdentity
のカスタマイズの詳細は、Quarkus の「Security tips and tricks」ガイドの Security identity customization セクションを参照してください。