该版本仍在开发中,尚未被视为稳定版本。如需获取最新的稳定版本,请使用Spring Vault 4.0.1spring-doc.cadn.net.cn

凭据轮换

Vault的全面凭证轮换功能支持自动更新和轮换密钥,例如数据库凭证。 通过将密钥的有效性与应用实例的生命周期绑定,您的应用能够在无需人工干预的情况下保持对有效凭证的访问。 受损的凭证仅在有限的时间内有效,并且影响范围被隔离到单个应用实例。spring-doc.cadn.net.cn

当一个密钥具有租约时,Spring Vault 会在其到期前续订该租约,从而在整个应用程序生命周期中保持凭证的有效性。spring-doc.cadn.net.cn

以下部分介绍了诸如属性源等组件所使用的凭据轮换基础设施。spring-doc.cadn.net.cn

秘钥租约容器

SecretLeaseContainer 管理租用密钥的生命周期。 它会在到期前续订租约,并在必要时轮换凭证,监听租约事件并触发适当的操作。spring-doc.cadn.net.cn

作为 Spring Lifecycle 组件,该容器支持在应用程序运行时进行动态密钥管理。 它接受 RequestedSecret 实例,表示被管理的密钥。spring-doc.cadn.net.cn

Example 1. Setting up a SecretLeaseContainer
SecretLeaseContainer container = new SecretLeaseContainer(vaultOperations,       (1)
    taskScheduler);

RequestedSecret requestedSecret = container                                      (2)
    .requestRotatingSecret("mysql/creds/my-role");

container.addLeaseListener(new LeaseListenerAdapter() {                          (3)

  @Override
  public void onLeaseEvent(SecretLeaseEvent secretLeaseEvent) {
    if (requestedSecret.equals(secretLeaseEvent.getSource())) {
      if (secretLeaseEvent instanceof SecretLeaseCreatedEvent) {
        // …
      }
      if (secretLeaseEvent instanceof SecretLeaseExpiredEvent) {
        // …
      }
    }
  }
});
container.afterPropertiesSet();
container.start(); // events are triggered after starting the container
1 使用 VaultOperationsTaskScheduler 进行初始化以用于续订调度。
2 从 Vault 路径请求一个轮换的密钥。
3 注册一个LeaseListener用于租约事件。 注册顺序很重要:在容器启动或密钥请求之后添加的监听器可能会错过早期事件。 在启动容器之前设置监听器以捕获所有事件。
当您的配置类是 AbstractVaultConfiguration 的子类时,通常会注册 SecretLaseContainer,这通常适用于非 Spring Boot 应用程序。 使用 Spring Boot 时,可以考虑 Spring Cloud Vault,它通过自动配置来处理注册。

事件

使用 SecretLeaseContainer 并结合其监听器可以直接对密钥的生命周期和租约事件的处理进行细粒度的控制。 在典型的应用场景中,您可能希望使用更高级别的抽象来简化密钥及其租约的管理。spring-doc.cadn.net.cn

ManagedSecret 和 SecretRegistrar

ManagedSecret API 提供了声明式的密钥生命周期管理。ManagedSecret 是一个更高级的抽象,它会向 SecretLeaseContainer 注册并代表您处理租约事件。 作为 SecretRegistrar 的实现,注册器 bean 会在启动之前通过 AbstractVaultConfiguration 向容器注册。spring-doc.cadn.net.cn

Example 2. 注册一个 ManagedSecret
@Configuration
class MyConfiguration {

  @Bean
  ManagedSecret mysqlCredentials(HikariDataSource dataSource) {
    return ManagedSecret.rotating("mysql/creds/my-role", secrets -> secrets.as(UsernamePassword::from)
          .applyTo((username, password) -> {
              connectionPool.setUsername(username);
              connectionPool.setPassword(password);
            }));
  }
}

Managed Secrets 允许在密钥管理与使用这些密钥的应用程序组件之间建立直接连接,从而在请求或轮换密钥时更容易将凭据传播到应用程序组件。 请注意,SecretLeaseContainers 生命周期的特性通常会推迟密钥的可用性,直到容器启动并且密钥被请求时才会提供,这可能不同于在 InitializingBean.afterPropertiesSet()@PostConstruct 阶段需要凭据的组件。 AbstractVaultConfiguration 有意在 Bean 创建期间就启动容器,以允许提前访问凭据。 在任何情况下,您都应确保组件的依赖顺序,以保证在需要时正确初始化并提供密钥。spring-doc.cadn.net.cn

TTL 调优

租约的续订和轮换受TTL(生存时间)影响,因此与时间直接相关。 SecretLeaseContainer 使用一个过期阈值(默认1分钟)来确定租约是否被视为过期。 最小续订TTL(默认10秒)防止在短时间内发出过多的续订请求。 续订和轮换时间根据租约TTL持续时间以及本地系统时钟(特别是 TaskScheduler 时钟)计算。spring-doc.cadn.net.cn

您可以配置一个自定义的过期Predicate<Lease>函数,用于确定租约是否到期。spring-doc.cadn.net.cn

Tokens续期与会话管理

Vault 在会话Tokens过期或被撤销时,会撤销与该会话关联的租约。 当您的 Vault 会话到期(达到最大 TTL)时,该会话内签发的所有租约也会被撤销。 SessionLeaseContainer 提供了一个 AuthenticationListener 通过 getAuthenticationListener()getAuthenticationErrorListener() 注册到您的 SessionManager,允许在成功重新登录后重启密钥。spring-doc.cadn.net.cn

证书容器

CertificateContainer 管理由 Vault 的 PKI 机密引擎颁发的证书。证书通常不与租约相关联(事实上,避免租约是一项性能优化建议),因此它们不需要续订,但在到期时可以进行轮换。证书轮换实际上是一种重新颁发。spring-doc.cadn.net.cn

Vault PKI 提供了多种证书类型:spring-doc.cadn.net.cn

容器是一个 Spring Lifecycle 组件,可以启动和停止,从而允许在应用程序运行时动态管理证书。 它接受 RequestedCertificate 实例,这些实例代表需要管理的证书。 以下代码示例展示了如何设置 CertificateContainer 并监听事件:spring-doc.cadn.net.cn

Example 3. Setting up a CertificateContainer
CertificateContainer container = new CertificateContainer(vaultOperations.opsForPki());  (1)

RequestedCertificate cert = container
  .register(RequestedCertificate.trustAnchor("vault-ca"));                               (2)

RequestedCertificate bundle = RequestedCertificateBundle.issue("www.example.com",        (3)
      "testrole", VaultCertificateRequest.builder()
              .commonName("www.example.com")
              .ttl(Duration.ofHours(12)).build());

container.addCertificateListener(new CertificateListenerAdapter() {                      (4)
  @Override
  public void onCertificateEvent(CertificateEvent event) {
    if (cert.equals(event.getSource())) {
      if (event instanceof CertificateBundleIssuedEvent) {
        // Certificate bundle issued initially or rotated
      }
      if (event instanceof CertificateObtainedEvent) {
        // initial certificate obtained
      }
    }
  }
});

container.afterPropertiesSet();
container.start(); // events are triggered after starting the container
1 使用 VaultPkiOperations 进行初始化。 如果没有提供 TaskScheduler,容器会创建一个默认实例。
2 通过 RequestedCertificate 请求颁发者证书(支持默认或命名的颁发者)。
3 通过 RequestedCertificateBundle 使用证书请求来申请托管的证书包。
4 注册一个CertificateListener用于证书事件。 注册顺序很重要:在容器启动或证书请求之后添加的监听器可能会错过早期事件。 在启动容器之前设置监听器以捕获所有事件。
当您的配置类是 AbstractVaultConfiguration 的子类时,通常会注册 CertificateContainer,这通常适用于非 Spring Boot 应用程序。 使用 Spring Boot 时,可以考虑 Spring Cloud Vault,它通过自动配置来处理注册。

事件

使用 CertificateContainer 并结合其监听器可以直接对证书的生命周期和事件处理进行细粒度的控制。 在典型的应用场景中,您可能希望使用更高级别的抽象来简化证书的管理。spring-doc.cadn.net.cn

ManagedCertificate 和 CertificateRegistrar

ManagedCertificate API 提供了声明式的证书生命周期管理。ManagedCertificate 是一个更高级的抽象,它会注册到 CertificateContainer 并代表您处理证书事件。 它是 CertificateRegistrar 的实现。 注册器 bean 会被 AbstractVaultConfiguration 检测到,并在容器启动之前注册到 CertificateContainerspring-doc.cadn.net.cn

Example 4. 注册一个 ManagedCertificate
@Configuration
class MyConfiguration {

  @Bean
  ManagedCertificate serverCertificate(SslBundles bundles) {
    VaultCertificateRequest request = VaultCertificateRequest.builder()
            .commonName("www.example.com")
            .ttl(Duration.ofHours(12)).build();
    return ManagedCertificate.issue("my-bundle", "my-role", request, bundle -> {
      bundles.register("my-bundle", bundle.createKeyStore("my-alias"));
   });
  }
}

Managed Certificates 允许在证书管理与使用证书的应用组件之间建立直接连接,从而使将凭证传播到应用组件更加容易。 请注意,CertificateContainer 生命周期的性质通常会将证书的可用性推迟到容器启动并且证书被请求时,这可能不同于在 InitializingBean.afterPropertiesSet()@PostConstruct 阶段需要凭证的组件。 AbstractVaultConfiguration 会在 bean 创建期间刻意提前启动容器,以允许早期访问证书。 在任何情况下,您都应该确保组件的依赖顺序,以保证在需要时正确初始化并提供证书。spring-doc.cadn.net.cn