Spring Boot API通过PCF Config Server连接HashiCorp Vault遇认证错误
正在将应用配置中的认证凭证迁移至HashiCorp Vault。原本在application.yml或bootstrap.yml中配置Vault可正常连接,但将Vault令牌配置移至PCF Config Server并部署代码到PCF时出现错误。
现有配置
Config Server配置JSON(vault-config)
{ "git": { "uri": "https://uri.com", "username": "user", "password": "pass" }, "vault": { "host": "hostname", "port": 443, "kvVersion": "2", "scheme": "https", "backend": "kv", "profile-separator": ",", "skipSslValidation": true, "namespace": "vault/my-app-namespace", "order": "1", "token": "token", "authentication": "token" } }
Git中的application.yml配置
my-app-username: ${my-app-username} my-app-password: ${my-app-password} spring: cloud: config: allow-override: true overrideSystemProperties: false overrideNone: true vault: kv: application-name: my-app
应用中的bootstrap.yml配置
spring: config: import: optional:vault:// cloud: config: allowOverride: true overrideSystemProperties: false overrideNone: true vault: enabled: true
部署错误信息
[APP/PROC/WEB/0] [OUT] 12:08:35.806 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed [APP/PROC/WEB/0] [OUT] java.lang.IllegalStateException: Cannot create authentication mechanism for TOKEN. This method requires either a Token (spring.cloud.vault.token) or a token file at ~/.vault-token. [APP/PROC/WEB/0] [OUT] at org.springframework.cloud.vault.config.ClientAuthenticationFactory.tokenAuthentication(ClientAuthenticationFactory.java:429) [APP/PROC/WEB/0] [OUT] at org.springframework.cloud.vault.config.ClientAuthenticationFactory.createClientAuthentication(ClientAuthenticationFactory.java:149) [APP/PROC/WEB/0] [OUT] at org.springframework.cloud.vault.config.VaultConfigDataLoader$ImperativeInfrastructure.lambda$registerClientAuthentication$4(VaultConfigDataLoader.java:512) [APP/PROC/WEB/0] [OUT] at org.springframework.boot.DefaultBootstrapContext.getInstance(DefaultBootstrapContext.java:119) [APP/PROC/WEB/0] [OUT] at org.springframework.boot.DefaultBootstrapContext.getOrElseThrow(DefaultBootstrapContext.java:111) [APP/PROC/WEB/0] [OUT] at org.springframework.boot.DefaultBootstrapContext.get(DefaultBootstrapContext.java:88)
需求:通过配置服务器集成Vault,且不在application.yml或bootstrap.yml中维护Vault相关配置,以便PCF同一空间的其他应用共享。
错误原因
当前配置让应用直接尝试连接Vault,但应用在bootstrap启动阶段还未从Config Server获取配置,因此无法拿到Vault令牌,导致认证失败。正确的模式应该是让PCF Config Server作为代理,从Vault拉取配置后再提供给应用,应用无需直接与Vault交互。
具体调整步骤
移除应用中直接连接Vault的配置
修改应用的bootstrap.yml,删除所有Vault相关配置,只保留Config Server的配置:spring: cloud: config: allowOverride: true overrideSystemProperties: false overrideNone: true同时删除Git中
application.yml里的spring.cloud.vault节点,最终Git中的application.yml应为:my-app-username: ${my-app-username} my-app-password: ${my-app-password} spring: cloud: config: allow-override: true overrideSystemProperties: false overrideNone: true确认Config Server的Vault配置正确性
保持现有Config Server的JSON配置不变,注意以下关键点:vault.order: 1确保Vault配置的优先级高于Git(如果需要优先从Vault获取配置)vault.namespace和vault.backend正确指向你的Vault路径,确保Config Server能拉取到my-app的配置vault.token有效,能让Config Server成功访问Vault
确保应用绑定到PCF Config Server
在PCF中,确保应用已正确绑定到Config Server实例,这样应用启动时会自动从Config Server获取所有配置(包括从Vault拉取的my-app-username和my-app-password)。验证配置生效
重新部署应用后,应用会通过Config Server获取Vault中的凭证,无需直接连接Vault,也不会再出现令牌缺失的错误。同一PCF空间的其他应用只需绑定到同一个Config Server,即可共享Vault集成的配置,无需重复配置Vault相关参数。
内容的提问来源于stack exchange,提问作者Spartan

