使用 Spring Boot 從 Secret Manager 擷取憑證/密鑰

1. 總覽

密碼、API 金鑰等密鑰屬於機密資訊,應儲存在安全加密的儲存空間中,並控管存取權及稽核。部分系統會選擇使用 Vault 儲存這些密鑰。在 Google Cloud 中,您可以使用受管理服務 Secret Manager 安全地儲存密鑰,並使用 IAM 控制個別密鑰的存取權。

在 Spring Boot 中,您可以透過 Spring Cloud GCP 輕鬆存取這些密鑰,方法是將密鑰視為任何其他 Spring 屬性。

在本程式碼研究室中,您將在 Secret Manager 中儲存密鑰,然後建構簡單的 Spring Boot 微服務並擷取密鑰。

課程內容

  • 如何建立 Spring Boot Java 應用程式及設定 Secret Manager。

軟硬體需求

  • Google Cloud 專案
  • ChromeFirefox 瀏覽器
  • 熟悉標準 Linux 文字編輯器,例如 Vim、EMAC 或 Nano

您會如何使用這項教學課程?

僅閱讀 閱讀並完成練習

您對建構 HTML/CSS 網頁應用程式的體驗滿意嗎?

新手 中級 熟練

您對使用 Google Cloud 服務的體驗滿意嗎?

新手 中級 熟練

2. 設定和需求

自修實驗室環境設定

  1. 登入 Cloud 控制台,建立新專案或重複使用現有專案。(如果沒有 Gmail 或 G Suite 帳戶,請先建立帳戶)。

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

請記住專案 ID,這是所有 Google Cloud 專案中不重複的名稱 (上述名稱已遭占用,因此不適用於您,抱歉!)。本程式碼研究室稍後會將其稱為 PROJECT_ID

  1. 接著,您必須在 Cloud 控制台中啟用帳單,才能使用 Google Cloud 資源。

完成本程式碼研究室的費用應該不高,甚至完全免費。請務必按照「清除」部分的指示操作,瞭解如何停用資源,避免在本教學課程結束後繼續產生帳單費用。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。

Google Cloud Shell

雖然您可以透過筆電遠端操作 Google Cloud 服務,但在本程式碼研究室中,我們將使用 Google Cloud Shell,這是可在雲端執行的指令列環境。

啟用 Cloud Shell

  1. 在 Cloud 控制台,點選「啟用 Cloud Shell」 圖示 H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-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 運作,大幅提升網路效能並強化驗證功能。本程式碼研究室幾乎所有工作都可在瀏覽器或 Chromebook 上完成。

連線至 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

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

這個指令使用 STDIN 將值提供給指令列。不過,您也可以直接將密鑰值放在檔案中,並為 --data-file 引數指定檔案名稱。

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

$ 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 屬性來源,因此您可以使用屬性值 (前置字元為 sm://) 參照密鑰,例如 sm://greeting

如要進一步瞭解屬性格式,請參閱 Spring Cloud GCP Secret Manager 說明文件。請注意,application.properties 是 Spring Cloud GCP 4.x 的新規定。詳情請參閱遷移指南

新增類別檔案,建立新的 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.png

5. 擷取 Secret

您可以使用 @Value 註解,透過 sm:// 前置字元參照密鑰屬性。

在 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」

更新密鑰值

使用 sm://greeting 短語法時,系統會自動使用最新版本的密鑰。建立新版密鑰後,您就能更新應用程式,不必變更程式碼。

新增版本來更新密鑰的值:

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

重新啟動應用程式,您會發現系統傳回新版密鑰。

執行中應用程式的螢幕截圖,顯示「Greetings World!」

擴展這個概念

如果您使用不同的 Spring Boot 應用程式設定檔,這項技術就特別實用。舉例來說,您可以建立 greeting-devgreeting-staginggreeting-prod 等密鑰。並在每個設定檔中,對應至正確的問候語。

建立 greeting-prod 密鑰:

$ 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 中儲存的密鑰進行設定,方法是使用以 sm:// 為前置字元的 Spring 屬性名稱,並從 applications.properties 檔案和 @Value 註解插入值。

7. 恭喜!

您已瞭解如何在 Java 中使用 Secret Manager API。

瞭解詳情

授權

這項內容採用的授權為 Creative Commons 姓名標示 2.0 通用授權。