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。
所需条件
您将如何使用本教程?
您如何评价自己在构建 HTML/CSS Web 应用方面的经验水平?
您如何评价自己在使用 Google Cloud 服务方面的经验水平?
<ph type="x-smartling-placeholder">2. 设置和要求
自定进度的环境设置
请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID
。
- 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。
运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。
Google Cloud Shell
虽然 Google Cloud 服务可以通过笔记本电脑远程操作,但在此 Codelab 中,我们将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
激活 Cloud Shell
- 在 Cloud Console 中,点击激活 Cloud Shell。
如果您以前从未启动过 Cloud Shell,将看到一个中间屏幕(在折叠下面),描述它是什么。如果是这种情况,请点击继续(您将永远不会再看到它)。一次性屏幕如下所示:
预配和连接到 Cloud Shell 只需花几分钟时间。
这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器或 Google Chromebook 即可完成本 Codelab 中的大部分(甚至全部)工作。
在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:
- 在 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 工具栏中的网页预览图标 ,然后选择在端口 8080 上预览。
短暂等待后,您应该会看到结果:
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 工具栏中的“网络预览”图标 ,然后选择在端口 8080 上预览。
短暂等待后,您应该会看到结果:
您还可以将该值映射到 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=-
重启应用,然后看到系统返回了新版本的密钥。
扩展这一概念
此方法在您使用其他 Spring Boot 应用配置文件时非常有用。例如,您可以创建 greeting-dev
、greeting-staging
、greeting-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 上预览。
短暂等待后,您应该会看到结果:
6. 总结
在本实验中,您创建了一项服务,该服务可以使用存储在 Secret Manager 中的 Secret 进行配置,方法是使用以 sm://
为前缀的 Spring 属性名称,并从 applications.properties
文件和 @Value
注解注入值。
7. 恭喜!
您学习了如何在 Java 中使用 Secret Manager API。
了解详情
- GCP 上的 Spring 项目:http://cloud.spring.io/spring-cloud-gcp/
- GCP GitHub 代码库上的 Spring:https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Google Cloud 上的 Java:https://cloud.google.com/java/
- 在 Secret Manager 中控制对 Secret 的访问权限:https://cloud.google.com/secret-manager/docs/access-control
- Secret Manager 中的审核日志记录:https://cloud.google.com/secret-manager/docs/audit-logging
许可
此作品已获得 Creative Commons Attribution 2.0 通用许可授权。