You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:37:04