在 Spring Boot 應用程式中從 Azure 金鑰保存庫 載入秘密
本教學課程說明如何在 Spring Boot 應用程式中使用 金鑰保存庫 來保護敏感數據,並從 金鑰保存庫 擷取組態屬性。 Key Vault 提供儲存通用祕密 (例如密碼和資料庫連接字串) 的安全機制。
必要條件
- Azure 訂用帳戶 - 建立免費帳戶。
- Java Development Kit (JDK) 第 8 版或更高版本。
- Apache Maven
- Azure CLI
- 金鑰保存庫 實例。 如果您沒有金鑰保存庫,請參閱快速入門:使用 Azure 入口網站 建立金鑰保存庫。 此外,請記下 金鑰保存庫 實例的 URI,因為您需要此教學課程的測試應用程式。
- Spring Boot 應用程式。 如果您沒有這個應用程式,請使用 Spring Initializr 來建立 Maven 專案。 請務必選取 Maven 專案,然後在 [相依性] 底下新增 Spring Web、Spring Data JPA 和 H2 資料庫相依性,然後選取 [Java 第 8 版] 或更新版本。
重要
需要 Spring Boot 2.5 版或更高版本,才能完成本文中的步驟。
將秘密設定為 Azure 金鑰保存庫
本教學課程說明如何在 Spring Boot 應用程式中從 金鑰保存庫 讀取資料庫認證。 若要從 金鑰保存庫 讀取認證,您應該先將資料庫認證儲存在 金鑰保存庫。
若要將 H2 資料庫的 URL 儲存為 金鑰保存庫 中的新秘密,請參閱快速入門:使用 Azure 入口網站 從 Azure 金鑰保存庫 設定和擷取秘密。 在本教學課程中,您將使用名稱和 h2url
值 jdbc:h2:~/testdb;user=sa;password=password
來設定秘密。
注意
設定秘密之後,請依照指派 金鑰保存庫 存取原則中的指示,將應用程式存取權授與 金鑰保存庫。
從 Azure 金鑰保存庫 讀取秘密
既然資料庫認證已儲存在 金鑰保存庫 中,您可以使用 Spring Cloud Azure 來擷取認證。
若要安裝 Spring Cloud Azure 金鑰保存庫 入門模組,請將下列相依性新增至您的 pom.xml 檔案:
Spring Cloud Azure 材料帳單(BOM):
<dependencyManagement> <dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-dependencies</artifactId> <version>5.19.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
注意
如果您使用 Spring Boot 2.x,請務必將
spring-cloud-azure-dependencies
版本設定為4.19.0
。 此材料帳單 (BOM) 應該在<dependencyManagement>
pom.xml檔案的 區段中設定。 這可確保所有 Spring Cloud Azure 相依性都使用相同的版本。 如需此 BOM 所用版本的詳細資訊,請參閱 應該使用哪個版本的 Spring Cloud Azure。Spring Cloud Azure 金鑰保存庫 入門成品:
<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-keyvault</artifactId> </dependency>
Spring Cloud Azure 有數種方法可從 金鑰保存庫 讀取秘密。 您可以獨立使用下列方法,或針對不同的使用案例加以合併:
- 使用適用於 金鑰保存庫的 Azure SDK。
- 使用 Spring KeyVault
PropertySource
。
使用 Azure SDK for 金鑰保存庫
適用於 金鑰保存庫的 Azure SDK 提供SecretClient
來管理 金鑰保存庫 中的秘密。
下列程式代碼範例將示範如何使用 SecretClient
從 Azure 金鑰保存庫 擷取 H2 資料庫認證。
若要從 金鑰保存庫 讀取使用 Azure SDK 的秘密,請遵循下列步驟來設定應用程式:
在 application.properties 組態檔中設定 金鑰保存庫 端點。
spring.cloud.azure.keyvault.secret.endpoint=https://<your-keyvault-name>.vault.azure.net/
在
SecretClient
Spring 應用程式中插入 bean,並使用getSecret
方法來擷取秘密,如下列範例所示:import com.azure.security.keyvault.secrets.SecretClient; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SecretClientApplication implements CommandLineRunner { // Spring Cloud Azure will automatically inject SecretClient in your ApplicationContext. private final SecretClient secretClient; public SecretClientApplication(SecretClient secretClient) { this.secretClient = secretClient; } public static void main(String[] args) { SpringApplication.run(SecretClientApplication.class, args); } @Override public void run(String... args) { System.out.println("h2url: " + secretClient.getSecret("h2url").getValue()); } }
提示
在本教學課程中,組態或程式代碼中沒有任何驗證作業。 不過,連線到 Azure 服務需要驗證。 若要完成驗證,您需要使用 Azure Identity。 Spring Cloud Azure 使用
DefaultAzureCredential
,Azure 身分識別連結庫會提供它來協助您取得認證,而不需要變更任何程序代碼。DefaultAzureCredential
支援多種驗證方法,並在執行階段判斷應使用的方法。 這種方法可讓您的應用程式在不同的環境中使用不同的驗證方法(例如本機和生產環境),而不需要實作環境特定的程序代碼。 如需詳細資訊,請參閱 DefaultAzureCredential。若要在本機開發環境中完成驗證,您可以使用 Azure CLI、Visual Studio Code、PowerShell 或其他方法。 如需詳細資訊,請參閱 Java 開發環境中的 Azure 驗證。 若要在 Azure 裝載環境中完成驗證,建議您使用使用者指派的受控識別。 如需詳細資訊,請參閱什麼是 Azure 資源受控識別?
啟動應用程式。 您會看到類似下列範例的記錄:
h2url: jdbc:h2:~/testdb;user=sa;password=password
您可以自行建 SecretClient
置豆,但程序很複雜。 在 Spring Boot 應用程式中,您必須管理屬性、了解產生器模式,以及向 Spring 應用程式內容註冊用戶端。 下列程式代碼範例示範如何建置 SecretClient
豆子:
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SecretClientConfiguration {
@Bean
public SecretClient createSecretClient() {
return new SecretClientBuilder()
.vaultUrl("https://<your-key-vault-url>.vault.azure.net/")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
}
}
下列清單顯示此程式代碼沒有彈性或正常運作的一些原因:
- 金鑰保存庫 端點會硬式編碼。
- 如果您使用
@Value
從 Spring 環境取得組態,則 application.properties 檔案中不能有 IDE 提示。 - 如果您有微服務案例,則必須在每個專案中複製程序代碼,而且很容易犯錯,而且很難保持一致。
幸運的是,使用 Spring Cloud Azure 不需要自行建 SecretClient
置豆子。 相反地,您可以直接插入SecretClient
並使用您已熟悉的設定屬性來設定 金鑰保存庫。 如需詳細資訊,請參閱 組態範例。
Spring Cloud Azure 也針對不同的案例提供下列全域設定。 如需詳細資訊,請參閱 Spring Cloud Azure 開發人員指南的 Azure 服務 SDK 全域設定一節。
- Proxy 選項。
- 重試選項。
- HTTP 傳輸客戶端選項。
您也可以連線到不同的 Azure 雲端。 如需詳細資訊,請參閱 連線到不同的 Azure 雲端。
使用 Spring 金鑰保存庫 PropertySource
前幾節說明如何在 應用程式啟動之後,在 SecretClient
中使用 CommandLineRunner
來讀取秘密。 不過,在 Spring Boot 應用程式中,應用程式啟動時需要讀取秘密。 例如,在應用程式啟動之前,需要數據源密碼屬性。 如果您想要將數據源密碼儲存在 金鑰保存庫 中,但仍使用 Spring 自動設定來取得數據源,則先前的案例將無法運作。
在此情況下,Spring Cloud Azure 會提供 Spring 環境整合,以在建置應用程式內容之前,從 金鑰保存庫 載入秘密。 您可以使用秘密在 Spring 應用程式內容初始化期間建構和設定 Bean。 這種方法是一種透明的方式,可讓您從 金鑰保存庫 存取秘密,而且不需要變更程序代碼。
下列程式代碼範例示範如何使用 PropertySource
擷取 H2 資料庫認證,從 Azure 金鑰保存庫 建置數據源。
若要從 金鑰保存庫 擷取 H2 資料庫的 URL,並使用 Spring Data JPA 從 H2 資料庫儲存數據,請遵循下列步驟來設定應用程式:
將下列 金鑰保存庫 端點和數據源屬性新增至 application.properties 組態檔。
logging.level.org.hibernate.SQL=DEBUG spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=https://<your-keyvault-name>.vault.azure.net/ spring.datasource.url=${h2url} spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
提示
如需 Spring Cloud Azure 屬性設定的範例,請參閱 Spring Cloud Azure 開發人員指南的設定範例一節。
提示
此範例是使用 H2 資料庫的簡單資料庫案例。 建議您在生產環境中使用 適用於 MySQL 的 Azure 資料庫 或 適用於 PostgreSQL 的 Azure 資料庫,並將資料庫 URL、使用者名稱和密碼儲存在 Azure 金鑰保存庫。 如果您想要避免密碼,無密碼連線是不錯的選擇。 如需詳細資訊,請參閱 Azure 服務的無密碼連線。
建立新的
Todo
Java 類別。 這個類別是對應至 JPA 自動建立之數據表的todo
網域模型。 下列程式代碼會getters
忽略和setters
方法。import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Todo { public Todo() { } public Todo(String description, String details, boolean done) { this.description = description; this.details = details; this.done = done; } @Id @GeneratedValue private Long id; private String description; private String details; private boolean done; }
編輯啟動類別檔案以顯示下列內容。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.JpaRepository; import java.util.stream.Stream; @SpringBootApplication public class KeyvaultApplication { public static void main(String[] args) { SpringApplication.run(KeyvaultApplication.class, args); } @Bean ApplicationListener<ApplicationReadyEvent> basicsApplicationListener(TodoRepository repository) { return event->repository .saveAll(Stream.of("A", "B", "C").map(name->new Todo("configuration", "congratulations, you have set up " + "correctly!", true)).toList()) .forEach(System.out::println); } } interface TodoRepository extends JpaRepository<Todo, Long> { }
啟動應用程式。 應用程式會從 金鑰保存庫 擷取 H2 資料庫的 URL,然後連線到 H2 資料庫,並將資料儲存至資料庫。 您會看到類似下列範例的記錄:
2023-01-13 15:51:35.498 DEBUG 5616 --- [main] org.hibernate.SQL: insert into todo (description, details, done, id) values (?, ?, ?, ?) com.contoso.keyvault.Todo@1f
部署至 Azure Spring Apps
現在您已在本機執行 Spring Boot 應用程式,現在可以將其移至生產環境。 Azure Spring Apps 可讓您輕鬆地將 Spring Boot 應用程式部署至 Azure,而不需要變更任何程式代碼。 服務會管理 Spring 應用程式的基礎結構,讓開發人員可以專注於處理程式碼。 Azure Spring 應用程式提供生命週期管理,使用全方位的監視和診斷、組態管理、服務探索、持續整合與持續傳遞的整合、藍綠部署等等。 若要將應用程式部署至 Azure Spring Apps,請參閱 將第一個應用程式部署至 Azure Spring Apps。