Spring Boot集成Vault(AppRole认证):无法用@Value/Environment读取属性
问题场景
我已将Spring应用配置为使用AppRole认证对接Vault,禁用了bootstrapping,通过编程方式处理AppRole认证。目前应用可通过VaultTemplate.read()方法访问Vault中的属性,但无法使用@Value注解或Environment Bean获取这些属性。
相关配置文件
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <spring-cloud.version>2023.0.2</spring-cloud.version> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-vault-config</artifactId> </dependency>
bootstrap.properties
spring.application.name=mnp spring.cloud.vault.authentication=approle spring.cloud.vault.uri=http://127.0.0.1:8200 spring.cloud.vault.kv.enabled=true spring.cloud.vault.kv.backend=secret
自定义Vault配置类
package com.hello.vaultDemo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.cloud.vault.config.SecretBackendConfigurer; import org.springframework.cloud.vault.config.VaultConfigurer; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; import org.springframework.vault.authentication.AppRoleAuthentication; import org.springframework.vault.authentication.AppRoleAuthenticationOptions; import org.springframework.vault.authentication.ClientAuthentication; import org.springframework.vault.client.VaultEndpoint; import org.springframework.vault.config.AbstractVaultConfiguration; @Configuration("CustomVaultConfiguration") public class CustomVaultConfiguration extends AbstractVaultConfiguration implements VaultConfigurer{ private static final Logger logger = LogManager.getLogger(CustomVaultConfiguration.class); @Override public VaultEndpoint vaultEndpoint() { return VaultEndpoint.from("http://127.0.0.1:8200"); } @Override public ClientAuthentication clientAuthentication() { try { String roleId = "d8de84ad-k201-48eb-5e8c-3d502b3e7496"; String secretId = "e5d8f8a3-8adc-312b-3a09-e494b09e1995"; AppRoleAuthenticationOptions.AppRoleAuthenticationOptionsBuilder builder = AppRoleAuthenticationOptions.builder().roleId(AppRoleAuthenticationOptions.RoleId.provided(roleId)).path("approle"); if (StringUtils.hasText(secretId)) { builder = builder.secretId(AppRoleAuthenticationOptions.SecretId.provided(secretId)); } return new AppRoleAuthentication(builder.build(), this.restOperations()); }catch (Exception ex){ logger.info("exception occurred while vault configuration, msg - {}", ex.getMessage(), ex); throw new Error("Failed to initialize vault!"); } } @Override public void addSecretBackends(SecretBackendConfigurer configurer) { configurer.add("secret/data/mnp"); } }
测试类及输出
package com.hello.vaultDemo; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import org.springframework.vault.core.VaultTemplate; import org.springframework.vault.support.VaultResponse; @Component public class test { @Value("${one:null}") String onee; @Value("${two:null}") String twoo; @Autowired VaultTemplate vaultTemplate; @Autowired Environment environment; @PostConstruct public void init() { VaultResponse response = vaultTemplate.read("secret/data/mnp"); System.out.println("response - "+ response.getData()); System.out.println("onee - "+ onee); System.out.println("twoo - "+ twoo); System.out.println("one "+environment.getProperty("one")); } }
输出结果:
response - {data={one=1, three=3, two=2}, metadata={created_time=2024-06-18T04:05:58.519111Z, custom_metadata=null, deletion_time=, destroyed=false, version=1}} onee - null twoo - null one null
解决方案
1. 指定KV版本
从输出可见你使用的是Vault KV v2版本(路径包含data),需在bootstrap.properties中明确配置KV版本:
spring.cloud.vault.kv.version=2
2. 调整Secret Backend路径
自定义配置类中addSecretBackends方法无需包含data后缀,Spring Cloud Vault会自动处理KV v2的路径转换,修改为:
@Override public void addSecretBackends(SecretBackendConfigurer configurer) { configurer.add("secret/mnp"); }
3. 确保配置加载生效
由于禁用了bootstrapping,需确保Spring Cloud Vault配置能在应用启动阶段加载到环境中:
- 若缺失依赖,添加
spring-cloud-starter-bootstrap:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
- 或在
application.properties中启用bootstrap:
spring.cloud.bootstrap.enabled=true
4. 检查配置优先级
确认没有本地配置文件(如application.properties)覆盖Vault中的属性,且Vault配置的加载优先级高于本地配置。
完成以上调整后重启应用,@Value注解和Environment即可正常读取Vault中的属性。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

