Spring Vault 2.1 实践

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

Spring Vault 2.1 即将发布。我想利用这篇文章更深入地了解即将发布版本中的更改和功能。

团队一直在开发大量新功能

  • 扩展基于基础设施的身份验证,以支持 Google Cloud IAM 和 Azure 托管服务标识

  • 集成 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 实例元数据服务 (IMDS) 获取 MSI 凭据。Vault 需要其他详细信息(subscriptionId、资源组名称、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());
  }

  // …
}

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

键值 API

Vault 在 0.10 版本中引入了其键值后端(在几个版本前也称为通用密钥后端)的版本化变体。此更改引入了另一种后端类型,其外部 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);

上面显示的变体忽略版本控制细节,即使目标密钥后端提供了这些细节。您可以获得一个版本化的键值 API 来与版本进行交互。VaultVersionedKeyValueOperations 公开了特定于版本的操作,例如检索特定密钥版本的特定版本或比较和设置。请查看以下示例

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));

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

包装 API 支持

Vault 中的核心概念是包装响应并返回一个令牌以获取实际的响应主体。响应包装现在由具有 VaultWrappingOperations 的专用 API 支持。包装支持允许查找包装的响应。您可以读取这些内容并重新包装内容。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 键值后端配置一起发布。我们持续关注 Vault 项目,并继续努力提供从应用程序角度来看有意义的功能的集成。干杯,敬请期待!

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以助您快速提升进度。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

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

查看全部