属性源

Vault 可以通过多种不同方式使用。其中一种特定的用例是使用 Vault 存储加密属性。Spring Vault 支持将 Vault 作为属性源,以便使用 Spring 的 PropertySource 抽象获取配置属性。

你可以在其他属性源中引用存储在 Vault 中的属性,或者使用 @Value(…) 进行值注入。当引导需要存储在 Vault 中的数据的 bean 时,需要特别注意。此时必须初始化一个 VaultPropertySource 以从 Vault 中检索属性。
Spring Boot/Spring Cloud 用户可以受益于 Spring Cloud Vault 的配置集成,它在应用程序启动期间初始化各种属性源。

注册 VaultPropertySource

Spring Vault 提供了一个 VaultPropertySource 与 Vault 一起使用以获取属性。它使用嵌套的 data 元素来暴露存储在 Vault 中并加密的属性。

ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));

在上面的代码中,VaultPropertySource 已以最高优先级添加到搜索中。如果它包含一个 ´foo` 属性,它将被检测到并优先于任何其他 PropertySource 中的任何 foo 属性返回。MutablePropertySources 暴露了许多方法,允许精确地操作属性源集。

@VaultPropertySource

@VaultPropertySource 注解提供了一种方便且声明性的机制,用于向 Spring 的 Environment 添加 PropertySource,以便与 @Configuration 类一起使用。

@VaultPropertySource 接受一个 Vault 路径,例如 secret/my-application,并暴露存储在该节点的数据作为 PropertySource@VaultPropertySource 支持与租约相关的 secrets(即 mysql 后端提供的凭据)的租约续期,并在租约到期时轮换凭据。租约续期默认禁用。

示例 1. 存储在 Vault 中的属性
{
  // …

  "data": {
    "database": {
      "password": ...
    },
    "user.name": ...,
  }

  // …
}
示例 2. 声明一个 @VaultPropertySource
@Configuration
@VaultPropertySource("secret/my-application")
public class AppConfig {

    @Autowired Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setUser(env.getProperty("user.name"));
        testBean.setPassword(env.getProperty("database.password"));
        return testBean;
    }
}
示例 3. 声明一个带有凭据轮换和前缀的 @VaultPropertySource
@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
  // provides aws.access_key and aws.secret_key properties
}
generic secret 后端获得的 secrets 关联有 TTL (refresh_interval),但没有租约 ID。当通用 secrets 达到其 TTL 时,Spring Vault 的 PropertySource 会对其进行轮换。
你可以使用 @VaultPropertySource 从版本化 Key-Value 后端获取最新的 secret 版本。请确保路径中不包含 data/ 段。

@VaultPropertySource 路径中存在的任何 ${…​} 占位符都会根据已注册到环境中的属性源集进行解析,如下例所示

示例 4. 使用占位符声明 @VaultPropertySource 路径
@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
}

假设 my.placeholder 存在于已注册的属性源(例如,系统属性或环境变量)之一中,占位符将被解析为相应的值。如果不存在,则使用 fallback/value 作为默认值。如果未指定默认值且无法解析属性,则会抛出 IllegalArgumentException

在某些情况下,使用 @VaultPropertySource 注解时,可能无法或不方便严格控制属性源的顺序。例如,如果上面的 @Configuration 类是通过组件扫描注册的,则顺序难以预测。在这种情况下——以及如果覆盖很重要——建议用户回退到使用编程方式的 PropertySource API。有关详细信息,请参阅 ConfigurableEnvironmentMutablePropertySources