Spring Vault 2.1 实操

工程 | Mark Paluch | 2018年9月24日 | ...

Spring Vault 2.1 已经提上日程。我想通过这篇博文深入探讨即将发布的版本中的更改和功能。

团队一直在努力开发许多新功能

  • 扩展基于基础设施的身份验证以支持 Google Cloud IAM 和 Azure Managed Service Identity

  • 集成 Vault 的版本化键值后端

  • 包装 API 支持

  • Java 11 兼容性

Spring Vault 支持 HashiCorp Vault 版本 0.5 到 0.11。您可以在 GitHub 上找到 Spring Vault 和 Spring Cloud Vault 的 示例仓库。现在,让我们深入了解 Spring Vault 2.1 的新功能!

Google Cloud 认证

随着 0.8.1 版本的发布,Vault 引入了对 Google Cloud 的认证支持。GCP 认证使用 GCP 的 IAM 服务,通过以下两种认证流程之一进行:

  • 使用服务账号凭据进行 IAM 登录,以生成签名令牌

  • 使用 GCP 的元数据服务进行 GCE 登录,以检索签名令牌

Spring Vault 支持这两种方法。虽然使用 IAM 认证需要设置凭据(通过环境变量或使用凭据文件),但 GCE 认证将平台作为身份提供者,因此 GCE 认证在初始设置方面的要求更少。

IAM 登录

IAM 认证使用 Google 的 IAM 服务,通过 Google 凭据的签名来生成签名令牌。签名令牌会被传递给 Vault 进行验证。此认证方法需要通过 GOOGLE_APPLICATION_CREDENTIALS 环境变量提供凭据,或者通过 GcpIamAuthenticationOptions 进行配置。GcpIamAuthentication 使用 Google 的服务 API SDK (google-api-services-iam) 与 IAM 进行交互。客户端配置可能如下面的代码示例所示:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {

  @Override
  public ClientAuthentication clientAuthentication() {

    try {

      GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder()
        .role("my-role")
        .credential(GoogleCredential.getApplicationDefault())
        .build();
      return new GcpIamAuthentication(options, restOperations());

    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
  }

  // …
}

默认情况下,IAM 认证方法从凭据中派生项目 ID 和服务账号 ID。您也可以配置特定的值,以便代表特定的服务账号进行认证。

有关更多信息,请参阅 参考文档

GCE 登录

GCE(Google Compute Engine)认证流程适用于虚拟机实例。它使用元数据服务(计算元数据)来获取签名令牌。签名身份被传递给 Vault 以验证虚拟机实例。客户端配置可能如下面的代码示例所示:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {

  @Override
  public ClientAuthentication clientAuthentication() {

    GcpComputeAuthenticationOptions options = GcpComputeAuthenticationOptions
        .builder().path("my-role").build();

    return new GcpComputeAuthentication(options, restOperations());
  }

  // …
}

有关更多信息,请参阅 参考文档

Azure 认证

随着 0.10.0 版本的发布,Vault 引入了对 Azure 的认证支持。运行在 Azure 虚拟机上的应用程序可以通过 托管服务标识 来向 Vault 进行认证。托管服务标识(MSI)可以为虚拟机激活,而无需预先配置凭据。

Spring Vault 从 Azure Instance Metadata Service (IMDS) 获取 MSI 凭据。Vault 需要额外的详细信息(订阅 ID、资源组名称、VM 名称)来执行认证。默认情况下,这些值也从 IMDS 获取,并与身份令牌一起传递给 Vault。可能的客户端配置可能如下面的代码示例所示:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {

  @Override
  public ClientAuthentication clientAuthentication() {

    AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
        .role("my-role").build();
    return new AzureMsiAuthentication(options, restOperations());
  }

  // …
}

有关更多信息,请参阅 参考文档

Key-Value API

Vault 在 0.10 版本中引入了其 Key-Value 后端(几年前也称为通用 secret 后端)的带版本变体。此更改引入了另一种后端类型,其操作(list、get、put、delete)的外部 API 相似,但 API 实现不同。

为了统一带版本和不带版本的 API 访问,我们引入了 VaultKeyValueOperations 作为通用 API。VaultKeyValueOperations 暴露了通用功能,如果您不想与版本控制元数据交互,可以使用它以版本无关的方式访问。以下示例显示了如何使用它:

VaultOperations vaultOperations = …
VaultKeyValueOperations operations = vaultOperations.opsForKeyValue("secret", KeyValueBackend.unversioned());

Map<String, Object> secret = new HashMap<>();
secret.put("key", "value");
secret.put("ttl", "5");

operations.put("key", secret);

operations.put("key", new Person(…));

VaultResponseSupport<Person> person = operations.get("key", Person.class);

上面显示的变体忽略了版本控制的细节,即使目标 secret 后端提供了这些细节。您可以获取带版本的 Key-Value API 来与版本进行交互。VaultVersionedKeyValueOperations 暴露了版本特定的操作,例如检索特定 secret 版本或进行比较并设置。请看以下示例:

VaultOperations vaultOperations = …
VaultVersionedKeyValueOperations operations = vaultOperations.opsForVersionedKeyValue("versioned");

Map<String, Object> secret = new HashMap<>();
secret.put("key", "value");
secret.put("ttl", "5");

Metadata metadata = operations.put("key", secret);

Versioned<Map<String, Object>> versioned = operations.get("key", Version.from(42));

Map<String, Object> update = new HashMap<>();
update.put("key", "new-key");
update.put("ttl", "5");

Versioned<Map<String, Object>> compareAndSet = Versioned.create(secret, versioned.getVersion());

operations.put("key", compareAndSet);

operations.delete("key", Version.from(42));

对带版本 secret 的请求和响应会将内容与版本控制元数据一起包装在 Versioned 对象中,以附加版本上下文。

Wrapping API 支持

Vault 的核心概念之一是包装响应并返回一个令牌以获取实际响应正文。响应包装现在由一个专用 API VaultWrappingOperations 提供支持。包装支持允许查找包装的响应。您可以读取这些响应并重新包装内容。VaultWrappingOperations 不支持 Spring Vault API 调用的响应包装。如果您需要创建包装的响应,可以直接通过 VaultOperations.doWithSession(…) 使用 RestTemplate

以下示例提供了 VaultWrappingOperations 用法的概述:

VaultOperations vaultOperations = …
VaultWrappingOperations operations = vaultOperations.opsForWrapping();

VaultToken wrappingToken = VaultToken.of(…);

// Metadata encapsulated TTL and Creation Time
WrappedMetadata lookup = operations.lookup(wrappingToken);

// Read the response as generic Map
VaultResponse response = operations.read(wrappingToken);

// Read the response applying a type hint.
VaultResponseSupport<SocialSecurityNumber> response = operations.read(
        wrappingToken, SocialSecurityNumber.class);

// You can also wrap user-supplied data and get a token in return
Map<String, String> map = Collections.singletonMap("key", "value");
WrappedMetadata metadata = wrappingOperations.wrap(map, Duration.ofSeconds(100));

Java 11 兼容性

Spring Vault 完全支持 Java 11,作为下一个长期支持版本。事实上,如果您正在为 JDK 11 开发,我们强烈建议您将 Spring Vault 版本升级到 2.1 版本(与 Spring Framework 5.1 结合使用),这将使您获得无警告的 Spring 库体验。所有 HTTP 客户端集成都支持 JDK 11。

展望

我们正致力于 Spring Vault 2.2 的下一个版本,该版本将提供带版本 Vault Key-Value 后端的基于注解的配置。我们将持续关注 Vault 项目,并继续努力为有意义的应用场景提供功能集成。祝您一切顺利,敬请关注!

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有