Spring Boot Vault Tutorial with Code Example (2021) | TechGeekNext >>




Spring Boot Vault Tutorial


The architecture of microservices has several services that communicate with each other and external resources such as databases. They will need access to usernames and passwords to access these resources. Normally, these credentials are stored in the config properties. Storing credentials the secure way is a challenge with limiting access and a true secure storage. So in this tutorial will see how implement Vault in Spring Boot to provide secure layer for sensitive data.

What is Vault?

Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, or certificates. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.

Why Vault is needed?

Storing secrets the secure way is a challenge with limiting access and a true secure storage. Passwords, API keys, secure Tokens, and confidential data are secrets sensitive data. Sensitive data can be encrypted by using the Spring Cloud Config Server. Encrypted data is one step better than unencrypted. However it needs decryption on the other side, which in turn requires a decryption key to be distributed. So the problem lies here, where to keep this decryption key, and can be attack vector if it's key is leaked.
It's difficult to do the right encryption, handling secrets is even tougher. Vault helps to address this problem and comes with encryption.

  1. Vault is a service to manage secrets.
  2. It provides an API that gives access to secrets based on policies.
  3. Any user of the API needs to authenticate and only sees the secrets for which he is authorized.
  4. The other major point is that Vault never stores a key in a persistent location.
  5. Starting/restarting Vault often needs one or more operators to unseal Vault.

What is Spring Cloud Vault?

Spring Cloud Vault is a configuration extension similar to Spring Cloud Config. Spring Cloud Config targets external configuration management backed by data stored in various repositories, such as GitHub, SVN or even Vault.

With Spring Cloud Vault you can access your secrets inside Vault. Secrets are picked up at startup of your application.
Include the Spring Cloud Vault starter in your project.

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

In this tutorial, will implement a simple Spring Boot Microservice which returns employee details from MySql Database. And will demonstrate the example how to secure database username and password using Vault. We will be creating the Spring Boot + MySQL Application. To begin with demo, will be initially showing how to install HashiCorp Vault to store secure data and then will point the Vault with Spring Boot Project by using Spring cloud Vault Config.

Vault Installation

  • Download from Vault Project as shown in below diagram.
  • This is a zip file. Unzip it contains vault.exe. Create a file name vaultconfig.hcl for configuring vault in same folder with below content.
    storage "file" {
    	path= "./vault-data"
    }
    
    
    listener "tcp" {
      address = "127.0.0.1:8200"
      tls_disable =1
    }
    
    disable_mlock=true
  • Open a command prompt and run the following vault commands.
  • vault server -config ./vaultconfig.hcl
    You can see Vault is now started.
  • Open another command prompt and run the following commands.
  • set VAULT_ADDR=http://localhost:8200
    
    vault operator init
  • Set token generated from above command as shown.
  • set VAULT_TOKEN=s.wO85qvAKuzL4QQifLE9N5aiq
  • See the Vault status
  • vault status

    We can see here that the Vault is sealed.
  • As shown above in status, need to unseal minimum 3 keys.
  • Unseal Key 1
    vault operator unseal bDB5qMRGeVFJ4R/JfW6+C6ciKlpMsgeNF7ZGx+KnFq1U
    

    Unseal Key 2
    vault operator unseal n8iCwwV1yrhQcTGMnkdnz5WQnEMviYLIa0RvOeFe9HOS

    Unseal Key 3
    vault operator unseal b7WhDdeLqdASVZlYVZBRtEO6Tz6h4o+vfBchpHMU/BzR
  • Next enable a key value store with named secrets.
    vault secrets enable -path=secret/ kv
    
  • Finally, store the MySql databse username and password in the Hashicorp Vault
  • vault kv put secret/techgeeknextApp dbusername=root
    vault kv put secret/techgeeknextApp dbpassword=root

Take a look at our suggested posts:

Now let's begin to create Spring Boot application to integrate with Vault.

Project Structure

Add Spring Cloud Vault Config dependency

In the pom.xml add the Spring Cloud Config Vault dependency for vault.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.techgeeknext</groupId>
	<artifactId>spring-boot-vault</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-vault</name>
	<description>Demo project for Spring Boot Vault</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-vault-config</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</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>

Configure properties

Create a file name bootstrap.yml under resources folder and add the following configuration.
spring:
  application:
    name: techgeeknextApp
  cloud:
    vault:
      host: localhost
      port: 8200
      scheme: http
      token: s.DpWuqkaCHybBTs6CKqIHgcH1
Now in the application.properties change the MySql database username and password properties to get values from Hashicorp Vault.
## Spring DATASOURCE
spring.datasource.url = jdbc:mysql://localhost:3306/employeedb?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false

## Point to Vault secure dbusername
spring.datasource.username=${dbusername}

## Point to Vault secure dbpassword
spring.datasource.password=${dbpassword}
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always

## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = create-drop
server.port=8002

Rest Controller

To test the application, create get all employees rest endpoint to get the employess details from database.
package com.techgeeknext.controller;

import com.techgeeknext.model.Employee;
import com.techgeeknext.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class EmployeeController {

	@Autowired
	EmployeeService employeeService;

	@RequestMapping(value = "/employees", method = RequestMethod.GET)
	public List<Employee> getEmployess() {
		return employeeService.getAllEmployees();
	}
}

Test

Test the application by calling GET employees rest endpoint http://localhost:8002/employees, and you can see all employees details are getting displayed on the screen.

Download Source Code

The full source code for this article can be found on below.
Download it here - Spring Boot Vault Integration
































Recommendation for Top Popular Post :