Spring Cloud Azure Key Vault 指南
一、概述
在本教程中,我們將探討雲原生開發的基本原則以及使用 Spring Cloud Azure Key Vault 的好處。
2.什麼是Spring Cloud Azure?
Spring Cloud Azure 是一套全面的庫和工具套件,專門設計用於促進 Spring 應用程序和 Microsoft Azure 服務之間的集成。
雖然已經可以將 Java 應用程序與Azure SDK集成,但 Spring Cloud Azure 的引入將這種集成提升到了一個全新的水平。
通過利用 Spring Cloud Azure 提供的一組強大的 API,我們可以方便地與各種 Azure 服務交互,例如Azure Storage 、 Cosmos DB等。
它**簡化了開發過程並增強了應用程序的整體安全性和性能**。
Spring Cloud Azure 提供了幾個模塊,用於將我們的應用程序與最相關的 Azure 服務集成。讓我們看幾個例子:
- 配置管理:使用
spring-cloud-azure-starter-appconfiguration
,我們可以輕鬆集成Azure 配置管理,這是一種管理和存儲部署在 Azure 上的應用程序配置的服務 - 存儲:借助
spring-cloud-azure-starter-storage
,我們可以無縫地使用Azure Storage這一基於雲的存儲解決方案來存儲和管理各種類型的數據,包括非結構化、結構化和半結構化數據 - Cosmos DB:配合
spring-cloud-azure-starter-cosmos
,可以順利集成Azure Cosmos DB多模型數據庫服務 - Service Bus:借助
[spring-cloud-azure-starter-servicebus](https://mvnrepository.com/artifact/com.microsoft.azure/spring-cloud-starter-azure-servicebus/1.2.8) ,
我們可以輕鬆集成Azure Service Bus ,這是一種消息服務,可以實現分佈式應用程序和服務之間的解耦通信 - Active Directory:使用
[spring-cloud-azure-starter-active-directory](https://mvnrepository.com/artifact/com.azure.spring/spring-cloud-azure-starter-active-directory/5.0.0) ,
使用Azure Active Directory ,可以輕鬆實現提供集中身份和訪問管理系統的服務
我們可以在這裡找到可用模塊的完整列表。
3.項目設置
要開始使用 Azure 雲服務,第一步是註冊Azure 訂閱。
訂閱到位後,讓我們安裝 Azure CLI 。這個命令行界面工具允許我們從本地機器與 Azure 服務進行交互。
接下來,讓我們打開命令提示符並運行命令:
> az login
登錄後,我們為訂閱創建一個新資源組:
>az group create --name spring_cloud_azure --location eastus
除了通過命令行創建資源組之外,我們還可以使用Web 瀏覽器中的 Azure 門戶創建新訂閱。這為管理我們的 Azure 資源和訂閱提供了一個直觀的界面。
隨著我們的前進,下一步是配置我們的 IDE。在本教程中,我們將使用 IntelliJ 作為我們選擇的 IDE。
**進行 Azure 相關開發時可以使用的一個有用工具包是Azure 工具包。**它提供了一組專門用於幫助開發人員在 Azure 平台上構建和管理應用程序的工具和資源。
因此,讓我們在我們的 IDE 上安裝這個插件,然後轉到Tools>Azure>Login
。這將提示我們輸入我們的 Azure 憑據以驗證我們對平台的訪問權限。
4.整合
我們已經完成了將 Spring 應用程序與 Azure 服務集成的必要準備工作。
在本教程中,我們將利用官方 Azure SDK for Java 和專用的 Spring Cloud 模塊將 Azure Key Vault 服務集成到我們的應用程序中。
4.1. Azure 密鑰保管庫
Azure Key Vault是一種基於雲的強大服務,它提供了一種安全可靠的方式來存儲和管理敏感數據,包括加密密鑰、機密和證書。
它可以充當應用程序的外部配置源。我們可以將敏感信息定義為 Azure Key Vault 中的機密,然後在運行時將它們安全地註入應用程序,而不是將敏感信息定義為配置文件中的值。
首先,我們需要在之前創建的資源組上創建一個新的 Key Vault。我們可以使用 Azure CLI 來執行此操作,但如果我們願意,也可以使用Azure 門戶:
> az keyvault create --name new_keyvault --resource-group spring_cloud_azure --location eastus
創建 Key Vault 存儲後,讓我們在 Key Vault 存儲new_keyvault
中創建兩個機密:
> az keyvault secret set --name my-database-secret --value my-database-secret-value --vault-name new_keyvault
> az keyvault secret set --name my-secret --value my-secret-value --vault-name new_keyvault
第一個密鑰具有密鑰my-database-secret
和值my-database-secret-value
,而第二個密鑰具有密鑰my-secret
和值my-secret-value
。
我們還可以在 Azure 門戶上檢查並確認這些機密的創建:
4.2.秘密客戶
一旦我們定義了這些秘密,我們就可以繼續在我們的應用程序上定義SecretClient
。
SecretClient
是一個提供客戶端接口的類,用於從 Azure Key Vault 檢索和管理機密。
那麼讓我們定義一個接口:
public interface KeyVaultClient {
SecretClient getSecretClient();
default KeyVaultSecret getSecret(String key) {
KeyVaultSecret secret;
try {
secret = getSecretClient().getSecret(key);
} catch (Exception ex) {
throw new NoSuchElementException(String.format("Unable to retrieve %s secret", key), ex);
}
return secret;
}
}
接口KeyVaultClient
聲明了兩個方法:
- 第一個方法
getSecretClient()
返回SecretClient
類的一個實例。 - 第二種方法
getSecret()
提供默認實現,用於從機密客戶端檢索嵌套在對象KeyVaultSecret
中的特定機密。
現在讓我們看看定義SecretClient
兩種方法,一種使用標準 Azure SDK,另一種使用 Spring Cloud 模塊。
4.3.沒有 Spring Cloud Azure 的集成
在這種方法中,我們將僅使用 Microsoft 的Azure SDK公開的 API 配置SecretClient
。
因此,讓我們將azure-keyvault-extensions
依賴項添加到我們的pom.xml
文件中:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-keyvault-extensions</artifactId>
<version>1.2.6</version>
</dependency>
現在讓我們在application.yaml
文件中定義配置SecretClient
的必要參數:
azure:
keyvault:
vaultUrl: {$myVaultUrl}
tenantId: {$myTenantId}
clientId: {$myClientId}
clientSecret: {$myClientSecret}
我們應該用適當的值替換所有佔位符。
一種選擇是將值直接硬編碼到application.yaml
中。但是,這種方法需要存儲多個敏感數據,包括clientId
或clientSecret
,這可能會帶來安全風險。
我們可以為每個敏感數據創建一個秘密,然後使用 Azure 管道將它們注入到我們的配置文件中,而不是對這些值進行硬編碼。
接下來,我們創建一個KeyVaultProperties
類來處理此配置:
@ConfigurationProperties("azure.keyvault")
@ConstructorBinding
public class KeyVaultProperties {
private String vaultUrl;
private String tenantId;
private String clientId;
private String clientSecret;
//Standard constructors, getters and setters
}
現在讓我們創建我們的客戶類:
@EnableConfigurationProperties(KeyVaultProperties.class)
@Component("KeyVaultManuallyConfiguredClient")
public class KeyVaultManuallyConfiguredClient implements KeyVaultClient {
private KeyVaultProperties keyVaultProperties;
private SecretClient secretClient;
@Override
public SecretClient getSecretClient() {
if (secretClient == null) {
secretClient = new SecretClientBuilder()
.vaultUrl(keyVaultProperties.getVaultUrl())
.credential(new ClientSecretCredentialBuilder()
.tenantId(keyVaultProperties.getTenantId())
.clientId(keyVaultProperties.getClientId())
.clientSecret(keyVaultProperties.getClientSecret())
.build())
.buildClient();
}
return secretClient;
}
}
一旦我們注入了KeyVaultClient
的這個實現, getSecret()
默認方法就會返回手動配置的SecretClient
對象。
4.4.與 Spring Cloud Azure 集成
作為此方法的一部分,我們將使用 Spring Cloud Azure Key Vault 設置SecretClient
並利用框架的另一個有用功能:將機密注入屬性文件。
因此,讓我們將spring-cloud-azure-starter-keyvault-secrets
依賴項添加到我們的pom.xml
文件中:
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
<version>5.0.0</version>
</dependency>
接下來,讓我們將以下屬性添加到我們的application.yaml
中:
spring:
cloud:
azure:
keyvault:
secret:
endpoint: {$key-vault-endpoint}
我們應該將key-vault-endpoint
佔位符替換為我們存儲的 URI,該 URI 在 Azure 門戶中Resources > {our keyvault} > Vault URI
下定義。
現在讓我們創建我們的客戶類:
@Component("KeyVaultAutoconfiguredClient")
public class KeyVaultAutoconfiguredClient implements KeyVaultClient {
private final SecretClient secretClient;
public KeyVaultAutoconfiguredClient(SecretClient secretClient) {
this.secretClient = secretClient;
}
@Override
public SecretClient getSecretClient() {
return secretClient;
}
}
一旦我們注入了KeyVaultClient
的實現, getSecret()
默認方法將返回自動配置的SecretClient
對象。除了端點機密外,沒有必要在我們的application.yaml
中指定任何配置值。
事實上,Spring Cloud 會自動填充所有SecretClient
的憑證參數。
使用 Spring Cloud Azure 模塊,我們也可以在我們的屬性文件中註入秘密。讓我們在application.yaml
中添加屬性:
spring:
cloud:
azure:
compatibility-verifier:
enabled: false
keyvault:
secret:
property-sources[0]:
name: key-vault-property-source-1
endpoint: https://spring-cloud-azure.vault.azure.net/
property-source-enabled: true
通過設置標誌property-source-enabled
,我們使 Spring Cloud Azure 能夠從keyvault-secret-property-sources[0]
中指定的 Key Vault 存儲注入秘密。
接下來,我們可以在application.yaml
中創建一個動態屬性:
database:
secret:
value: ${my-database-secret}
當應用程序啟動時,Spring Cloud Azure 將${my-database-secret}
佔位符替換為 Azure Key Vault 中定義的秘密my-database-secret
的實際值。
4.5.在屬性文件中註入秘密
我們已經看到了兩種將秘密注入我們的屬性文件的方法:使用 Spring Cloud Azure Key Vault 或配置 Azure 管道。
如果我們只使用 Spring Cloud Azure Key Vault,我們應該在application.yaml
中對 Key Vault 端點進行硬編碼,以在我們的屬性文件中啟用注入,這可能會帶來安全風險。
另一方面,使用 Azure 管道,無需對任何值進行硬編碼。管道將替換我們的application.yaml.
因此,我們應該僅使用 Spring Cloud Azure Key Vault 模塊來獲得自動配置的SecretClient
和其他功能的好處,同時將機密注入到我們的屬性文件中委託給 Azure 管道。
4.6.運行應用程序
現在讓我們運行我們的 Spring Boot 應用程序:
@SpringBootApplication
public class Application implements CommandLineRunner {
@Value("${database.secret.value}")
private String mySecret;
private final KeyVaultClient keyVaultClient;
public Application(@Qualifier(value = "KeyVaultAutoconfiguredClient") KeyVaultAutoconfiguredClient keyVaultAutoconfiguredClient) {
this.keyVaultClient = keyVaultAutoconfiguredClient;
}
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Override
public void run(String... args) throws Exception {
KeyVaultSecret keyVaultSecret = keyVaultClient.getSecret("my-secret");
System.out.println("Hey, our secret is here ->" + keyVaultSecret.getValue());
System.out.println("Hey, our secret is here from application properties file ->" + mySecret);
}
}
我們的應用程序將從自動配置的客戶端和啟動時注入到application.yaml
中的密鑰中檢索密鑰,然後將兩者顯示在控制台上。
5.結論
在本文中,我們討論了 Spring Cloud 與 Azure 的集成。
我們了解到,使用 Spring Cloud Azure Key Vault 而不是 Microsoft 提供的 Azure SDK,可以更簡單、更簡潔地集成 Azure Key Vault 和 Spring 應用程序。
與往常一樣,可以 在 GitHub 上找到示例的完整源代碼。