Naveen Kumar
Naveen Kumar

Reputation: 109

Spring Cloud Vault - Missing required header: X-Config-Token

I was following the getting started guides for spring config server and vault when I run into a issue related to vault I am unable to resolve. The config server is however working fine with GIT but not with Vault. Below is the code and config I am using -

Here is the configserver code -

@EnableConfigServer
@SpringBootApplication
   public class SpringConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringConfigServerApplication.class, args);
    }

}

And the corresponding application.yml -

spring:
  application:
    name: configserver
  cloud:
    config:
      server:
        vault:
          port: 8200
          host: 127.0.0.1
        git:
          uri: https://github.com/weekly-drafts/config-repo-spring-cloud-configserver-vault
  profiles:
    active: default, native, git, vault
server:
  port: 8888

configserver pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.rockingengineering</groupId>
<artifactId>spring-config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>spring-config-server</name>
<description>Spring Config Server Application</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath />
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

Here is my configclient code

@SpringBootApplication
public class VaultApplication {

    public static void main(String[] args) {
      SpringApplication.run(VaultApplication.class, args);
    }
}

and property loading controller. This code is loading properties from GIT but not vault.

@RefreshScope
@RestController
public class VaultController {

  @Value("${client.pseudo.property}")
  private String pseudoProperty;

  @Value("${client.pseudo.property.vault}")
  private String proeprtyFromVault;

  @GetMapping("/property")
  public ResponseEntity<String> getProperty() {
      return ResponseEntity.ok(pseudoProperty);
  }

  @GetMapping("/property/vault")
  public ResponseEntity<String> getPropertyFromVault() {
      return ResponseEntity.ok(proeprtyFromVault);
  }
}

Configclient bootstrap.yml -

spring:
  application:
    name: configclient
  cloud:
    vault:
      token: f474964a-89bf-39e6-2e37-3d7de918f762
      uri: http://localhost:8888
    config:
      token: f474964a-89bf-39e6-2e37-3d7de918f762
      uri: http://localhost:8888
      headers:
        X-Vault-Token: f474964a-89bf-39e6-2e37-3d7de918f762
server:
  port: 8080

ConfigClient pom.xml -

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.rockingengineering</groupId>
<artifactId>spring-cloud-vault</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<name>spring-cloud-vault</name>
<description>Spring Cloud Vault Application</description>
<inceptionYear>2018</inceptionYear>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath />
</parent>

<properties>
    <spring-cloud-vault-dependencies.version>1.0.2.RELEASE</spring-cloud-vault-dependencies.version>

    <log4j.version>1.2.17</log4j.version>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-vault-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>3.0-alpha-1</version>
        <scope>provided</scope>
    </dependency>

</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <finalName>spring-cloud-vault</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

Response from Vault -

vault kv get -format=json secret/configclient
{
  "request_id": "1a8dba22-d120-f7b9-13a2-8f2107786c29",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "data": {
      "client.pseudo.property.vault": "Property value loaded from Vault"
    },
    "metadata": {
      "created_time": "2018-10-11T12:36:24.165749Z",
      "deletion_time": "",
      "destroyed": false,
      "version": 2
    }
  },
  "warnings": null
}

I am able to use vault from CLI using the same token. The error I am getting is -

2018-10-11 18:07:49.946  INFO 97999 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3fc2959f: startup date [Thu Oct 11 18:07:49 IST 2018]; root of context hierarchy
2018-10-11 18:07:50.389  INFO 97999 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$c21aa722] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-10-11 18:07:50.913  INFO 97999 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.5.RELEASE)

2018-10-11 18:07:53.579  WARN 97999 --- [           main] o.s.v.a.LifecycleAwareSessionManager     : Cannot enhance VaultToken to a LoginToken: Token self-lookup failed: 500 {"timestamp":"2018-10-11T12:37:53.557+0000","status":500,"error":"Internal Server Error","message":"No such label: token","path":"/v1/auth/token/lookup-self"}
2018-10-11 18:07:53.603  WARN 97999 --- [           main] LeaseEventPublisher$LoggingErrorListener : [RequestedSecret [path='secret/configclient', mode=ROTATE]] Lease [leaseId='null', leaseDuration=PT0S, renewable=false] Status 400 secret/configclient: {"timestamp":"2018-10-11T12:37:53.594+0000","status":400,"error":"Bad Request","message":"Missing required header: X-Config-Token","path":"/v1/secret/configclient"}

2018-10-11 18:07:53.632  WARN 97999 --- [           main] LeaseEventPublisher$LoggingErrorListener : [RequestedSecret [path='secret/application', mode=ROTATE]] Lease [leaseId='null', leaseDuration=PT0S, renewable=false] Status 400 secret/application: {"timestamp":"2018-10-11T12:37:53.630+0000","status":400,"error":"Bad Request","message":"Missing required header: X-Config-Token","path":"/v1/secret/application"}

org.springframework.vault.VaultException: Status 400 secret/application: {"timestamp":"2018-10-11T12:37:53.630+0000","status":400,"error":"Bad Request","message":"Missing required header: X-Config-Token","path":"/v1/secret/application"}
    at org.springframework.vault.client.VaultResponses.buildException(VaultResponses.java:89) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.client.VaultResponses.buildException(VaultResponses.java:81) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.VaultTemplate.lambda$doRead$1(VaultTemplate.java:328) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.VaultTemplate.doWithSession(VaultTemplate.java:307) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.VaultTemplate.doRead(VaultTemplate.java:317) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.VaultTemplate.read(VaultTemplate.java:212) ~[spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.lease.SecretLeaseContainer.doGetSecrets(SecretLeaseContainer.java:545) [spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.lease.SecretLeaseContainer.start(SecretLeaseContainer.java:357) [spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.lease.SecretLeaseContainer.addRequestedSecret(SecretLeaseContainer.java:316) [spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.env.LeaseAwareVaultPropertySource.loadProperties(LeaseAwareVaultPropertySource.java:147) [spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.vault.core.env.LeaseAwareVaultPropertySource.<init>(LeaseAwareVaultPropertySource.java:133) [spring-vault-core-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.vault.config.LeasingVaultPropertySourceLocator.createVaultPropertySource(LeasingVaultPropertySourceLocator.java:151) [spring-cloud-vault-config-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.vault.config.LeasingVaultPropertySourceLocator.createVaultPropertySource(LeasingVaultPropertySourceLocator.java:88) [spring-cloud-vault-config-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.vault.config.VaultPropertySourceLocatorSupport.doCreatePropertySources(VaultPropertySourceLocatorSupport.java:170) [spring-cloud-vault-config-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.vault.config.VaultPropertySourceLocatorSupport.createCompositePropertySource(VaultPropertySourceLocatorSupport.java:145) [spring-cloud-vault-config-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.vault.config.VaultPropertySourceLocatorSupport.locate(VaultPropertySourceLocatorSupport.java:116) [spring-cloud-vault-config-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:94) [spring-cloud-context-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:654) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:390) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:331) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at com.rockingengineering.vault.VaultApplication.main(VaultApplication.java:10) [classes/:na]

2018-10-11 18:07:53.633  INFO 97999 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='vault', propertySources=[LeaseAwareVaultPropertySource {name='secret/configclient'}, LeaseAwareVaultPropertySource {name='secret/application'}]}
2018-10-11 18:07:53.639  INFO 97999 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8888
2018-10-11 18:07:56.496  INFO 97999 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=configclient, profiles=[default], label=null, version=null, state=null
2018-10-11 18:07:56.496  INFO 97999 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='https://github.com/weekly-drafts/config-repo-spring-cloud-configserver-vault/configclient.yml'}]}
2018-10-11 18:07:56.502  INFO 97999 --- [           main] c.r.vault.VaultApplication               : No active profile set, falling back to default profiles: default
2018-10-11 18:07:56.516  INFO 97999 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@60a2630a: startup date [Thu Oct 11 18:07:56 IST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@3fc2959f
2018-10-11 18:07:57.909  INFO 97999 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=e9255d82-de63-3800-b389-53a2229e780a
2018-10-11 18:07:58.032  INFO 97999 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$c21aa722] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-10-11 18:07:58.564  INFO 97999 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2018-10-11 18:07:58.589  INFO 97999 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-10-11 18:07:58.589  INFO 97999 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.34
2018-10-11 18:07:58.593  INFO 97999 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/naveen/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2018-10-11 18:07:58.706  INFO 97999 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-10-11 18:07:58.706  INFO 97999 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2190 ms
2018-10-11 18:07:59.377  INFO 97999 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2018-10-11 18:07:59.965  INFO 97999 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/property],methods=[GET]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.rockingengineering.vault.controller.VaultController.getProperty()
2018-10-11 18:07:59.966  INFO 97999 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/property/vault],methods=[GET]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.rockingengineering.vault.controller.VaultController.getPropertyFromVault()
2018-10-11 18:07:59.969  INFO 97999 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/v2/api-docs],methods=[GET],produces=[application/json || application/hal+json]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)
2018-10-11 18:08:00.101  INFO 97999 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2018-10-11 18:08:00.116  INFO 97999 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-10-11 18:08:00.117  INFO 97999 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-10-11 18:08:00.118  INFO 97999 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-10-11 18:08:00.266  INFO 97999 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-11 18:08:00.397  INFO 97999 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@60a2630a: startup date [Thu Oct 11 18:07:56 IST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@3fc2959f
2018-10-11 18:08:00.443  INFO 97999 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-11 18:08:00.443  INFO 97999 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-11 18:08:00.798  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-10-11 18:08:00.811  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'environmentManager' has been autodetected for JMX exposure
2018-10-11 18:08:00.812  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshScope' has been autodetected for JMX exposure
2018-10-11 18:08:00.815  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
2018-10-11 18:08:00.821  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
2018-10-11 18:08:00.831  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
2018-10-11 18:08:00.842  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=60a2630a,type=ConfigurationPropertiesRebinder]
2018-10-11 18:08:00.985  INFO 97999 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2018-10-11 18:08:00.986  INFO 97999 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed
2018-10-11 18:08:01.004  INFO 97999 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2018-10-11 18:08:01.016  INFO 97999 --- [           main] s.d.s.w.s.ApiListingReferenceScanner     : Scanning for api listing references
2018-10-11 18:08:01.099  WARN 97999 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.vaultController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'client.pseudo.property.vault' in value "${client.pseudo.property.vault}"
2018-10-11 18:08:01.101  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2018-10-11 18:08:01.102  INFO 97999 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans
2018-10-11 18:08:01.107  INFO 97999 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2018-10-11 18:08:01.131  INFO 97999 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-10-11 18:08:01.138 ERROR 97999 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.vaultController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'client.pseudo.property.vault' in value "${client.pseudo.property.vault}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:378) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:353) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:390) ~[spring-cloud-context-2.0.1.RELEASE.jar:2.0.1.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at com.rockingengineering.vault.VaultApplication.main(VaultApplication.java:10) [classes/:na]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'client.pseudo.property.vault' in value "${client.pseudo.property.vault}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:237) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:211) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ... 33 common frames omitted

2018-10-11 18:08:01.139  INFO 97999 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3fc2959f: startup date [Thu Oct 11 18:07:49 IST 2018]; root of context hierarchy
2018-10-11 18:08:01.141  INFO 97999 --- [       Thread-2] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService

Can anyone tell what I am missing here?

Upvotes: 2

Views: 7564

Answers (2)

nmyk
nmyk

Reputation: 1622

  1. You don't need to use spring-cloud-starter-vault-config for your config-client in this particular case. Basically your client doesn't know anything about Vault. You just need to pass token (spring.cloud.config.token) and config-server will take care of getting properties from Vault using this token. spring-cloud-starter-vault-config is used in case when you want to get data directly from Vault (not through config-server). Your configuration (bootstrap.yml) should look like this:

    spring:
      application:
        name: configclient
      cloud:
        config:
          token: your_vault_token
          uri: http://localhost:8888
    
  2. In config-server you need to support composite configuration from git and Vault. So you need to put 2 profiles: git and vault.

  3. The tricky moment is that Vault has now 2 versions for KV Secrets Engine (https://www.vaultproject.io/api/secret/kv/index.html) so make sure that you use same version in vault and config-server. Because based on documentation kv version 2 is enabled by default in dev mode:

Additionally, when running a dev-mode server, the v2 kv secrets engine is enabled by default at the path secret/ (for non-dev servers, it is currently v1). It can be disabled, moved, or enabled multiple times at different paths. Each instance of the KV secrets engine is isolated and unique.

See: https://www.vaultproject.io/docs/secrets/kv/kv-v2.html

Spring Cloud Config has support of both versions of Vault KV storage:

Vault 0.10.0 introduced a versioned key-value backend (k/v backend version 2) that exposes a different API than earlier versions, it now requires a data/ between the mount path and the actual context path and wraps secrets in a data object. Setting kvVersion=2 will take this into account. More: http://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.0.1.RELEASE/single/spring-cloud-config.html#vault-backend

So based on all of this information, you configserver application.yml should look like this:

server:
  port: 8888
spring: 
  application:
    name: configserver
  profiles:
    active: git, vault
  cloud:
    config:
      server:
        vault:
          port: 8200
          host: 127.0.0.1
          kvVersion: 2  #may be 1 depends on Vault configuration
        git:
          uri: https://github.com/weekly-drafts/config-repo-spring-cloud-configserver-vault

Upvotes: 4

zetta
zetta

Reputation: 954

The right configuration is spring.cloud.config.token, you have the right config in the wrong file. Try adding it in application.yml instead, basically everything that comes before the Spring Boot Logo is configured through bootstrap.yml after the logo, Spring unloads bootstrap.yml and loads application.yml and then it tries to get the configuration from Spring Config Server.

What I usually do is to add is as an environment variable (SPRING_CLOUD_CONFIG_TOKEN), so no matter when it tries to reach the config, the value will be there.

Upvotes: 1

Related Questions