如何在Spring Boot启动时将Azure KeyVault属性加载到PropertySource
Spring Boot启动时加载Azure KeyVault属性到高优先级PropertySources解决方案
1. 添加必要依赖
直接引入Spring Cloud Azure KeyVault Starter和Jasypt Starter,保证版本兼容:
<!-- Maven 依赖 --> <dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId> <version>4.12.0</version> <!-- 替换为最新稳定版 --> </dependency> <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.5</version> </dependency>
2. 清晰配置凭证与优先级
不用依赖自动配置的隐式逻辑,直接在配置文件里明确KeyVault连接信息和优先级,数值越小优先级越高(确保覆盖本地配置):
# application.yaml spring: cloud: azure: keyvault: secrets: property-sources: - name: my-keyvault vault-url: https://你的密钥库名称.vault.azure.net/ credential: client-id: ${AZURE_CLIENT_ID} # 从环境变量读取,避免硬编码 client-secret: ${AZURE_CLIENT_SECRET} tenant-id: ${AZURE_TENANT_ID} enabled: true priority: 0 # 设为0,确保优先级高于本地配置文件
3. 自定义加载逻辑(官方Starter不满足时用)
如果官方Starter的自动配置不符合需求,自己实现EnvironmentPostProcessor,手动加载KeyVault属性并放到最前面:
编写处理器类
import com.azure.identity.ClientSecretCredential; import com.azure.identity.ClientSecretCredentialBuilder; import com.azure.security.keyvault.secrets.SecretClient; import com.azure.security.keyvault.secrets.SecretClientBuilder; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import java.util.HashMap; import java.util.Map; public class AzureKeyVaultEnvironmentPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { // 从环境变量/本地配置读取凭证参数 String clientId = environment.getProperty("azure.client.id"); String clientSecret = environment.getProperty("azure.client.secret"); String tenantId = environment.getProperty("azure.tenant.id"); String vaultUrl = environment.getProperty("azure.keyvault.url"); // 创建凭证与密钥客户端 ClientSecretCredential credential = new ClientSecretCredentialBuilder() .clientId(clientId) .clientSecret(clientSecret) .tenantId(tenantId) .build(); SecretClient secretClient = new SecretClientBuilder() .vaultUrl(vaultUrl) .credential(credential) .build(); // 加载所有密钥到Map Map<String, Object> keyVaultProps = new HashMap<>(); secretClient.listPropertiesOfSecrets().forEach(secretProp -> { KeyVaultSecret secret = secretClient.getSecret(secretProp.getName()); keyVaultProps.put(secret.getName(), secret.getValue()); }); // 将KeyVault属性放到最高优先级的PropertySource environment.getPropertySources().addFirst(new MapPropertySource("azure-keyvault-props", keyVaultProps)); } }
注册处理器
在src/main/resources/META-INF/spring.factories里添加:
org.springframework.boot.env.EnvironmentPostProcessor=你的包路径.AzureKeyVaultEnvironmentPostProcessor
4. 兼容Jasypt解密
如果KeyVault中存储的是ENC()格式的加密值,无需额外配置——Jasypt的环境处理器会自动解密所有PropertySource中的加密属性,只要你的KeyVault PropertySource优先级正确,解密逻辑会自动覆盖本地配置。
5. 验证优先级
启动应用后,可通过接口打印PropertySource顺序,确认KeyVault属性排在最前面:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.PropertySource; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PropCheckController { @Autowired private ConfigurableEnvironment env; @GetMapping("/prop-sources") public String listPropSources() { StringBuilder sb = new StringBuilder(); for (PropertySource<?> source : env.getPropertySources()) { sb.append(source.getName()).append(" - ").append(source.getClass().getName()).append("<br>"); } return sb.toString(); } }
内容的提问来源于stack exchange,提问作者Mike Rother
相关产品推荐
相关产品推荐

