0

I have been trying to use the authentication method from Hashicorp Vault (from here) in my application to get configurations.

But not able to get any information regarding this authentication type in Spring's docs, examples, etc. Can you please help me out as I need this type of authentication to help me with vault in multiuser environment.

ndmeiri
  • 4,979
  • 12
  • 37
  • 45
  • 1
    Please share your code here... – Onic Team Apr 04 '18 at 12:59
  • I don't have any code regarding this, I just wanted to know if **spring-vault** or **spring-cloud-vault** implements all the authentication methods given by the **Hashicorp Vault's** authentication APIs or just the ones I can google because I'm trying to implement **Spring-cloud-config** methodology for my application using Vault. – Keshav Bohra Apr 05 '18 at 06:27
  • Have you checked out the docs? https://cloud.spring.io/spring-cloud-vault/single/spring-cloud-vault.html#vault.config.authentication – mp911de Apr 05 '18 at 19:13
  • Yes but it doesn't have the userpass authentication method. It has app-id method which is deprecated and replaced by approle, but the userpass method is different than the app-id/approle method. – Keshav Bohra Apr 09 '18 at 09:53

2 Answers2

4

Here is my solution:

Configuration class:

package com.company.myapp.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.vault.VaultException;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;

@Configuration
public class VaultConfig {

    public static final String LOGIN_PATH = "/v1/auth/userpass/login/";

    @Bean
    public ClientAuthentication clientAuthentication(@Value("${VAULT_USERNAME}") String username,
                                                     @Value("${VAULT_PASSWORD}") String password,
                                                     @Value("${spring.cloud.vault.uri}") String host) {
        return new UserPassAuthentication(host, LOGIN_PATH, username, password);
    }

    public static class UserPassAuthentication implements ClientAuthentication {

        private RestOperations restOperations = new RestTemplate();

        private String url;

        private String password;

        public UserPassAuthentication(String host, String path, String user, String password) {
            this.url = new StringBuilder(host).append(path).append(user).toString();
            this.password = password;
        }

      @Override
    public VaultToken login() throws VaultException {
        return VaultToken.of(
                ((Map<String, String>) restOperations.postForEntity(url, new Password(password), Map.class)
                        .getBody().get("auth")).get("client_token"));
    }
}

static class Password {
    private String password;

    public Password(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

resources/bootstrap.properties:

spring.profiles.active=dev

spring.application.name=myapp
spring.cloud.vault.kv.enabled=true
spring.cloud.vault.kv.backend=test-backend

spring.cloud.vault.uri=https://localhost:8200
VAULT_USERNAME=usr
VAULT_PASSWORD=pwd

resources/META-INF/spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration=com.company.myapp.config.VaultConfig
  • The above config throws `BeanDefinitionStoreException` as the bean clientAuthentication is already created by spring. Any other things to do apart from above code. – Antony Vimal Raj May 18 '22 at 07:43
0

Using this solution I had 2 problems.

  1. overriding spring preconfigured beans.

solution: add

spring.main.allow-bean-definition-overriding =true

in your bootstrap.properties file. this allows bean definition overriding.

  1. beanInstantiationException: Because authentication steps were not defined properly. solution: I used the token authentication method as follows:
     public ClientAuthentication clientAuthentication()  {
         return new TokenAuthentication(new UserPassAuthentication("host", path, "user", "password").login());
     }
    

and the rest of the code exactly as shown before.