使用凭据提供程序
与数据存储交互通常意味着首先使用凭据连接。 这些凭据将允许客户端被识别、身份验证,并最终被授权。 基于用户名/密码的身份验证非常常见,但这绝不是唯一的方式。 此类凭据信息可能会出现在应用程序配置中,但将此类敏感信息存储在安全存储中正变得越来越流行,例如 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
)会将其凭据提供程序返回的任何属性添加到其连接配置中,而不仅仅是用户名和密码。 因此,在设计新的凭据提供程序时,请将属性限制为消费者可以理解的内容,或提供适当的配置选项以支持不同的模式。