使用 Spring Boot 从 Secret Manager 检索凭据/Secret

1. 概览

密码、API 密钥等密钥是敏感信息,应存储在安全的加密存储空间内,支持访问控制和审核。有些系统选择使用保险柜来存储这些密钥。在 Google Cloud 上,您可以使用代管式服务 Secret Manager 安全地存储 Secret,并使用 IAM 控制对各个 Secret 的访问权限。

在 Spring Boot 中,您可以使用 Spring Cloud GCP 轻松访问这些 Secret,只需将其称为任何其他 Spring 属性即可。

在此 Codelab 中,您将在 Secret Manager 中存储一个 Secret,然后构建简单的 Spring Boot 微服务并检索 Secret。

学习内容

  • 如何创建 Spring Boot Java 应用并配置 Secret Manager。

所需条件

  • Google Cloud 项目
  • 一个浏览器,例如 ChromeFirefox
  • 熟悉标准的 Linux 文本编辑器,例如 Vim、EMACs 或 Nano

您将如何使用本教程?

仅阅读教程内容 阅读并完成练习

您如何评价自己在构建 HTML/CSS Web 应用方面的经验水平?

新手水平 中等水平 熟练水平

您如何评价自己在使用 Google Cloud 服务方面的经验水平?

<ph type="x-smartling-placeholder"></ph> 新手 中级 熟练

2. 设置和要求

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 (如果您还没有 Gmail 或 G Suite 账号,则必须创建一个。)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

Google Cloud Shell

虽然 Google Cloud 服务可以通过笔记本电脑远程操作,但在此 Codelab 中,我们将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

激活 Cloud Shell

  1. 在 Cloud Console 中,点击激活 Cloud ShellH7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

如果您以前从未启动过 Cloud Shell,将看到一个中间屏幕(在折叠下面),描述它是什么。如果是这种情况,请点击继续(您将永远不会再看到它)。一次性屏幕如下所示:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

预配和连接到 Cloud Shell 只需花几分钟时间。

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器或 Google Chromebook 即可完成本 Codelab 中的大部分(甚至全部)工作。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:

  1. 在 Cloud Shell 中运行以下命令以确认您已通过身份验证:
gcloud auth list

命令输出

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果不是上述结果,您可以使用以下命令进行设置:

gcloud config set project <PROJECT_ID>

命令输出

Updated property [core/project].

3. 配置 Secret

如需使用 Secret Manager,请先启用 API:

$ gcloud services enable secretmanager.googleapis.com

然后,创建一个名为 greeting 且值为 Hello 的 Secret:

$ echo -n "Hello" | \
 gcloud secrets create greeting \
 --data-file=-

此命令使用 STDIN 向命令行提供值。但是,您也可以简单地将 Secret 值放在文件中,并为 --data-file 参数指定文件名。

您可以使用 gcloud CLI 列出所有 Secret:

$ gcloud secrets list

4. 创建新的 Spring Boot REST 服务

启动 Cloud Shell 后,您可以使用命令行通过 Spring Initializr 生成新的 Spring Boot 应用:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d dependencies=web,cloud-gcp \
  -d bootVersion=3.0.6 \
  -d type=maven-project \
  -d baseDir=hello-secret-manager | tar -xzvf - \
  && cd hello-secret-manager

pom.xml 中,添加 Spring Cloud GCP 起始依赖项:

pom.xml

<project>
  ...

  <dependencies>
    ...
    <!-- Add Secret Manager Starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
    </dependency>
  </dependencies>

  ...
</project>

src/main/resources/application.properties 文件中,添加以下配置以启用 Spring Boot Config Data API

spring.config.import=sm://

这将配置 Spring Property Source,以便您可以使用前缀为 sm:// 的属性值引用 Secret,例如 sm://greeting

如需详细了解属性的格式,请参阅 Spring Cloud GCP Secret Manager 文档。请注意,Spring Cloud GCP 4.x 中新增了 application.properties 要求。如需了解详情,请参阅迁移指南

通过添加新的类文件来创建新的 REST 控制器:

src/main/java/com/example/demo/HelloSecretController.java

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloSecretController {
  String greeting = "Hi";

  @GetMapping("/")
  public String hello() {
    return greeting + " World!";
  }
}

您可以使用 Spring Boot 插件正常启动 Spring Boot 应用。

确保 JAVA_HOME 设置为正确的 JDK 版本:

$ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

我们跳过此实验的测试,直接启动应用:

$ ./mvnw -DskipTests spring-boot:run

应用启动后,点击 Cloud Shell 工具栏中的网页预览图标 e18df08334f0d809.png,然后选择在端口 8080 上预览

短暂等待后,您应该会看到结果:

1e9a7884ff113c14

5. 检索 Secret

您可以使用 @Value 注解来引用使用 sm:// 前缀的 Secret 属性。

在 HelloSecretController 类中,使用注解注入 greeting 值:

src/main/java/com/example/demo/HelloSecretController.java

import org.springframework.beans.factory.annotation.Value;

...

@RestController
public class HelloSecretController {
  @Value("${sm://greeting}")
  String greeting;

  ...
}

您可以使用 Spring Boot 插件正常启动 Spring Boot 应用。我们跳过此实验室的测试:

$ ./mvnw -DskipTests spring-boot:run

应用启动后,点击 Cloud Shell 工具栏中的“网络预览”图标 e18df08334f0d809.png,然后选择在端口 8080 上预览

短暂等待后,您应该会看到结果:

正在运行的应用的屏幕截图,其中显示了“Hello World!”

您还可以将该值映射到 application.properties 中的属性:

src/main/resources/application.properties

greeting=${sm://greeting}

在 HelloSecretController 中,您可以引用此更通用的属性名称,而不是 Secret Manager 名称:

src/main/java/com/example/demo/HelloSecretController.java

@RestController
public class HelloSecretController {
  @Value("${greeting}")
  String greeting;
  ...
}

您可以使用 Spring Boot 插件正常启动 Spring Boot 应用。我们跳过此实验室的测试:

$ ./mvnw -DskipTests spring-boot:run

应用启动后,点击 Cloud Shell 工具栏中的网页预览图标 “网页预览”图标,然后选择在端口 8080 上预览

更新 Secret 值

使用 sm://greeting 简短语法时,系统会自动使用最新版本的 Secret。通过创建新版 Secret,您可以在不更改代码的情况下更新应用。

通过添加新版本来更新 Secret 的值:

$ echo -n "Greetings" |
 gcloud secrets versions add greeting \
 --data-file=-

重启应用,然后看到系统返回了新版本的密钥。

正在运行的应用的屏幕截图,其中显示了“Greeings World!”

扩展这一概念

此方法在您使用其他 Spring Boot 应用配置文件时非常有用。例如,您可以创建 greeting-devgreeting-staginggreeting-prod 等 Secret。在每个个人资料中,映射到相应的问候语。

创建 greeting-prod Secret:

$ echo -n "Hola" | \
 gcloud secrets create greeting-prod \
 --data-file=- --replication-policy=automatic

创建 application-prod.properties 文件:

src/main/resources/application-prod.properties

greeting=${sm://greeting-prod}

您可以使用 Spring Boot 插件正常启动 Spring Boot 应用,但使用 prod 配置文件。我们跳过此实验室的测试:

$ ./mvnw -DskipTests spring-boot:run -Dspring-boot.run.profiles=prod

应用启动后,点击 Cloud Shell 工具栏中的“网络预览”图标 网络预览图标,然后选择在端口 8080 上预览

短暂等待后,您应该会看到结果:

正在运行的应用的屏幕截图,其中显示了“Hola World!”

6. 总结

在本实验中,您创建了一项服务,该服务可以使用存储在 Secret Manager 中的 Secret 进行配置,方法是使用以 sm:// 为前缀的 Spring 属性名称,并从 applications.properties 文件和 @Value 注解注入值。

7. 恭喜!

您学习了如何在 Java 中使用 Secret Manager API。

了解详情

许可

此作品已获得 Creative Commons Attribution 2.0 通用许可授权。