使用凭据提供程序
与数据存储交互通常意味着首先使用凭据连接。 这些凭据将允许客户端被识别、身份验证,并最终被授权。 基于用户名/密码的身份验证非常常见,但这绝不是唯一的方式。 此类凭据信息可能会出现在应用程序配置中,但将此类敏感信息存储在安全存储中正变得越来越流行,例如 HashiCorp Vault、Azure Key Vault 或 AWS Secrets Manager 等。
为了桥接消耗凭据(可以采用不同的形式)的数据存储和提供这些凭据的安全存储,Quarkus 引入了一个名为 Credentials Provider 的中间抽象,一些扩展可能会支持它来使用凭据(例如 agroal),而另一些扩展可能会实现它来生成凭据(例如 vault)。
想要支持 Quarkus 中尚未实现的自定义提供程序的实现者也可以使用此服务编程接口 (SPI)(例如 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 的其他注意事项。
|
此技术被认为是预览版。 在预览中,不保证向后兼容性和在生态系统中的存在。 具体改进可能需要更改配置或 API,并且成为稳定版本的计划正在进行中。 欢迎在我们的邮件列表或作为我们的GitHub 问题跟踪器中的问题提出反馈。 有关可能的完整状态列表,请查看我们的常见问题解答条目。 |
Vault 凭据提供程序
要配置 Vault Credentials Provider,您需要提供以下属性
quarkus.vault.credentials-provider.<name>.<property>=<value>
<name> 将在消费者中用于引用此提供程序。 <property> 和 <value> 字段特定于 Vault Credentials Provider。 有关完整详细信息,请参阅 https://docs.quarkiverse.io/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://:5432/mydatabase
请注意,quarkus.datasource.username 是原始的 agroal 属性,而 password 属性未包含在内,因为该值将来自我们刚刚定义的 mydatabase 凭据提供程序。 另一种方法是在 Vault 中定义用户名和密码,并从配置中删除 quarkus.datasource.username 属性。 所有消费扩展都支持从提供程序获取用户名和密码,或者仅获取密码。
限时凭据
凭据提供程序可以提供限时凭据。 例如,vault 扩展。 使用限时凭据时,重要的是要了解消费扩展不会由凭据提供程序自动刷新其凭据。 必须配置每个扩展才能在凭据过期之前回收其连接。
自定义凭据提供程序
当 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://: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)会将其凭据提供程序返回的任何属性添加到其连接配置中,而不仅仅是用户名和密码。 因此,在设计新的凭据提供程序时,请将属性限制为消费者可以理解的内容,或提供适当的配置选项以支持不同的模式。