クレデンシャルプロバイダーの使用
データストアとのやりとりは、通常、最初にクレデンシャルを使用して接続することを意味します。これらのクレデンシャルによって、クライアントは識別され、認証され、最終的には認可されるようになります。ユーザー名/パスワードベースの認証は非常に一般的ですが、それだけではありません。このようなクレデンシャル情報はアプリケーションの設定に存在するかもしれませんが、HashiCorp Vault、Azure Key Vault、AWS Secrets Managerなどのセキュアなストアにこのタイプの機密情報を保存することが一般的になってきています。
さまざまな形式をとることができるクレデンシャルを消費するデータストアと、それらのクレデンシャルを提供する安全なストアの橋渡しをするために、Quarkusでは、 Credentials Provider
と呼ばれる中間的な抽象化を導入しています。これは、一部のエクステンションがクレデンシャルを消費するためにサポートしている場合もあれば(例: agroal
)、クレデンシャルを生成するために実装している場合もあります(例: vault
)。
このService Programming Interface(SPI)は、Quarkusにまだ実装されていないカスタムプロバイダ(Azure Key Vaultなど)をサポートしたい実装者が使用することもできます。
現在、 Credentials Provider
インターフェイスは vault
エクステンションによって実装されており、以下のクレデンシャルコンシューマーエクステンションによってサポートされています。
-
agroal
-
reactive-db2-client
-
reactive-mysql-client
-
reactive-mssql-client
-
reactive-oracle-client
-
reactive-pg-client
-
oidc
-
oidc-client
-
messaging-rabbitmq
ユーザー名/パスワード認証に依存するすべてのエクステンションでは、代替として application.properties
で設定プロパティーを設定することもできます。しかし、クレデンシャルが生成されている場合 (例: Vault Dynamic DB Credentials
) やカスタムのクレデンシャルプロバイダが必要な場合は Credentials Provider
が唯一のオプションです。
このガイドでは、 vault
エクステンションで提供されている Credentials Provider
の使い方を紹介し、次にカスタム Credentials Provider
の実装について見ていき、最後に新しいエクステンションで Credentials Provider
を実装する際の追加考慮事項について説明します。
この技術は、previewと考えられています。 preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリスト や GitHub の課題管理 で受け付けています。 とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。 |
Vault Credentials Provider
Vault Credentials Provider
を設定するには、以下のプロパティーを提供する必要があります。
quarkus.vault.credentials-provider.<name>.<property>=<value>
<name>
は、コンシューマーがこのプロバイダーを参照するために使用されます。 <property>
および <value>
フィールドは、 Vault Credentials Provider
に特有です。完全な詳細については、https://quarkiverse.github.io/quarkiverse-docs/quarkus-vault/dev/vault-datasource.htmlを参照してください。
例えば
quarkus.vault.credentials-provider.mydatabase.kv-path=myapps/vault-quickstart/db
一度定義すると、 mydatabase
プロバイダーは Credentials Provider
インターフェイスをサポートするすべてのエクステンションで使用することができます。例えば、 agroal
の場合次のようになります:
# configure your datasource
quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = sarah
quarkus.datasource.credentials-provider = mydatabase
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase
quarkus.datasource.username
はオリジナルの agroal
プロパティですが、値は先ほど定義した mydatabase`クレデンシャルプロバイダーから取得されるため、`password
プロパティは含まれていません。 別の方法としては、Vault でユーザー名とパスワードの両方を定義し、設定から プロパティーを削除する方法があります。すべてのコンシューマーエクステンションは、ユーザー名とパスワードの両方をプロバイダから取得する機能、またはパスワードのみを取得する機能をサポートしています。
期間限定クレデンシャル
クレデンシャルプロバイダは、期間限定クレデンシャルを提供することができます。
たとえば、 vault
エクステンション。期限付きクレデンシャルを使用する場合、消費するエクステンションはクレデンシャルプロバイダによって自動的にクレデンシャルをリフレッシュされないことを理解することが重要です。
各エクステンションは、クレデンシャルの有効期限が切れる前に接続をリサイクルするように設定する必要があります。
データソース
データストア接続は通常プールされます。
期間限定クレデンシャルプロバイダーを使用する場合、各接続のクレデンシャルの有効期限が切れる前に接続をリサイクルするようにプールを構成する必要があります。JDBC と Reactive データソースの両方には、これを実現するために使用できる max-lifetime
設定プロパティがあります。
quarkus.datasource.jdbc.max-lifetime=60m
quarkus.datasource.reactive.max-lifetime=60m
データソースの max-lifetime プロパティの設定が、資格情報の有効期限よりも短いことを確認するのは、開発者の責任です。
|
カスタムクレデンシャルプロバイダー
カスタムクレデンシャルプロバイダーの実装は、QuarkusでVault製品がまだサポートされていない場合や、カスタムストアからクレデンシャルを取得する必要がある場合の唯一のオプションです。
実装するインターフェースはこれだけです。
public interface CredentialsProvider {
String USER_PROPERTY_NAME = "user";
String PASSWORD_PROPERTY_NAME = "password";
Map<String, String> getCredentials(String credentialsProviderName);
}
USER_PROPERTY_NAME
と PASSWORD_PROPERTY_NAME
は、ユーザー名/パスワードベースの認証をサポートするすべてのコンシューマーエクステンションで認識されるべき標準的なプロパティーです。
実装は有効な @ApplicationScoped
CDI Beanであることが要求されます。
簡単な例を挙げてみます。
@ApplicationScoped
@Unremovable
public class MyCredentialsProvider implements CredentialsProvider {
@Override
public Map<String, String> getCredentials(String credentialsProviderName) {
Map<String, String> properties = new HashMap<>();
properties.put(USER_PROPERTY_NAME, "hibernate_orm_test");
properties.put(PASSWORD_PROPERTY_NAME, "hibernate_orm_test");
return properties;
}
}
ここでは、ユーザー名とパスワードの両方を返すことにしました。
このプロバイダは、次のようなデータソースの定義で使用することができます。
quarkus.datasource.db-kind=postgresql
quarkus.datasource.credentials-provider=custom
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5431/hibernate_orm_test
標準的なMicroProfile Configインジェクションを使用して、設定プロパティーをプロバイダに渡すことも可能です。
custom.foo=bar
そして、プロバイダの実装では
@Inject
Config config;
@Override
public Map<String, String> getCredentials(String credentialsProviderName) {
System.out.println("MyCredentialsProvider called with foo=" + config.getValue(credentialsProviderName + ".foo", String.class));
...
}
新しいクレデンシャルプロバイダーエクステンション
新しいエクステンションでカスタムクレデンシャルプロバイダーを作成する際には、いくつかの追加考慮事項があります。
まず、プロジェクト内で複数のクレデンシャルプロバイダーが利用可能な場合の衝突を避けるために、名前を付ける必要があります。
@ApplicationScoped
@Unremovable
@Named("my-credentials-provider")
public class MyCredentialsProvider implements CredentialsProvider {
credentials-provider-name
のプロパティを許可するのはコンシューマーの責任です。
quarkus.datasource.credentials-provider = custom
quarkus.datasource.credentials-provider-name = my-credentials-provider
エクステンションでは、 vault
エクステンションの CredentialsProviderConfig
のように、ランタイム設定でプロバイダー内の任意のカスタムプロパティーを設定できるようにしておく必要があります。AWS Secrets Managerエクステンションの場合は、次のようになります。
-
region
-
credentials-type
-
secrets-id
また、 agroal
のようなコンシューマーの中には、ユーザー名とパスワードだけでなく、クレデンシャル・プロバイダが返すプロパティーを接続設定に追加するものがあることにも注意してください。したがって、新しいクレデンシャル・プロバイダーを設計する際には、プロパティーをコンシューマーが理解できるものに限定するか、または異なるモードをサポートするための適切な設定オプションを提供してください。