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
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.auth.permission.default.paths=/*
quarkus.http.auth.permission.default.policy=authenticated
quarkus.http.insecure-requests=disabled
- 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
quarkus.http.auth.permission.certauthenticated.paths=/*
quarkus.http.auth.permission.certauthenticated.policy=role-policy-cert
quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin
上記の設定では、クライアント証明書の CN 属性が alice または bob の場合にリクエストが認可され、jdoe の場合はリクエストが拒否されます。