Spring EnableEncryptableProperties with Jasypt shows an example how to avoid putting clear text password for database connection credentials in properties file. Jasypt means Java simplified encryption. Here we are going to use Spring version 4 with Jasypt (Java simplified encryption). Here we are also going to use Spring Data JPA to perform the data layer activities with database.

If you put clear text password in properties file then everybody even people who should not see password would gain access to your database and may change database tables values, structure or even may delete without your consent. So it is always better to put the password in an encypted way to avoid such unwanted issues.

Here we will create Gradle based Spring Boot application with Spring Data JPA and apply Jasypt (Java simplified encryption) to extra layer of security for your password.

Jasypt Spring Boot provides Encryption support for property sources in Spring Boot Applications. There are 3 ways to integrate Jasypt in your spring boot project:

Simply adding the starter jar jasypt-spring-boot-starter to your classpath if using @SpringBootApplication or @EnableAutoConfiguration will enable encryptable properties across the entire Spring Environment

Adding jasypt-spring-boot-starter to your classpath and adding @EnableEncryptableProperties to your main Configuration class to enable encryptable properties across the entire Spring Environment

Adding jasypt-spring-boot-starter to your classpath and declaring individual encryptable property sources with @EncrytablePropertySource

Here I will show you an example on adding jasypt-spring-boot-starter to classpath and adding @EnableEncryptableProperties to Configuration class to enable encryptable properties.

You may also like to read:

Batch Insert using Spring JdbcTemplate

Transaction Management in Spring

Hibernate UserType using Spring Data JPA

Spring Data JPA Batch Insertion

Spring Data JPA Entity Auditing using EntityListeners

Spring Data JPA Entity Graph

Spring Data JPA CRUD Example

Prerequisites

Knowledge of Java, Spring

Softwares

Eclipse
JDK 1.8
Gradle 4
Spring, Jasypt, Oracle driver, Hibernate dependencies

Setting Up Project

Create Gradle project called SpringBootEncryptablePropertiesJasypt in Eclipse and build the blank project. Your project should build fine.

Modify your build.gradle script with the following source code in order to add required depencies and configurations.

Notice we have added depency compile(“com.github.ulisesbocchio:jasypt-spring-boot-starter:2.0.0”) for integrating Spring EnableEncryptableProperties  with Jasypt.

buildscript {
	ext {
		springBootVersion = '1.5.9.RELEASE'
	}
    repositories {
		mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'SpringBootEncryptablePropertiesJasypt'
    version = '0.0.1-SNAPSHOT'
    manifest {
        attributes("Main-Class": "com.jeejava.main.Application")
    }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
	mavenLocal()
    mavenCentral()
}
    
dependencies {
	compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
	compile("com.github.ulisesbocchio:jasypt-spring-boot-starter:2.0.0")
	compile("org.springframework.boot:spring-boot-starter-data-jpa")
	compile("com.oracle.jdbc:ojdbc7:12.1.0.2")
	compile("org.hibernate:hibernate-java8")
}

Creating application.properties

Create application.properties file under classpath directory src/main/resources with the following source code.

In this file we have basically put the Oracle database configurations. You need to change according to your database host, port, service name, username and password or you can use database of your choice. Here you see we have added ENC() method to let spring know that we are setting encrypted password and it needs to be decrypted while spring tries to establish the connection with database. This is where the example shows how Spring EnableEncryptableProperties with Jasypt (Java simplified encryption) works.

Now check we have added another line jasypt.encryptor.password=test (you can have other values as per your choice) and it is required to to decrypt your encrypted password. This value was used while we encrypted the database password and passed the encrypted password into ENC() method.

Now while spring tries to connect to database, it first decrypts the encrypted password using jasypt.encryptor.password (here the value is ‘test’) and connects to database. If you do not want to keep this jasypt.encryptor.password in application.properties file then you can pass this as VM argument (-Djasypt.encryptor.password=test) while you are running the application.

If you want you can encrypt every key/value pair of the application.properties file but only the password field is sensitive so we have encrypted only password here.

By default the Jasypt uses PBEWITHMD5ANDDES algorithm for encrypt/decrypt.

#datasource
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect
spring.datasource.url=jdbc:Oracle:thin:@//<host>:<port>/<service name>
spring.datasource.username=<username>
spring.datasource.password=ENC(zuflTEjtJTv+XWLf8y8KbYSuoUIWAsYG)

jasypt.encryptor.password=test

server.port=9999

#disable schema generation from Hibernate
spring.jpa.hibernate.ddl-auto=none

Now create below Java classes to complete the example integrating Spring EnableEncryptableProperties with Jasypt (Java simplified encryption).

Creating Entity Class

Suppose we have a region table that stores all regions available in the world and we have the following entity class with the below attributes and corresponding columns in the region table. I have removed the getters and setters you can generate from option in Eclipse.

package com.jeejava.entity;

import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "region")
public class Region implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id")
	private Integer id;
	@Column(name = "name")
	private String name;
	@Column(name = "shot_desc")
	private String shortDesc;
	//getters and setters
}

Creating Configuration Class

We will use annotation based configurations, so we need following configuration class in order to use Spring EnableEncryptableProperties annotaion along with DataSource configuration for database.

We are using Spring Data JPA to perform query on database, so we have defined spring beans EntityManagerFactory and DataSource.

We have configured JPA Repositories using annotaion EnableJpaRepositories.

We have also let spring know where entity class is kept using factory.setPackagesToScan(“com.jeejava.entity”).

package com.jeejava.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;

@Configuration
@EnableEncryptableProperties
@EnableJpaRepositories(basePackages = "com.jeejava.repository")
public class DatabaseConfig {
	@Autowired
	private Environment environment;
	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource ds = new DriverManagerDataSource();
		ds.setDriverClassName(environment.getRequiredProperty("spring.datasource.driverClassName"));
		ds.setUrl(environment.getRequiredProperty("spring.datasource.url"));
		ds.setUsername(environment.getRequiredProperty("spring.datasource.username"));
		ds.setPassword(environment.getRequiredProperty("spring.datasource.password"));
		return ds;
	}
	@Bean
	public EntityManagerFactory entityManagerFactory(DataSource dataSource) {
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		vendorAdapter.setDatabase(Database.ORACLE);
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		factory.setJpaVendorAdapter(vendorAdapter);
		factory.setPackagesToScan("com.jeejava.entity");
		factory.setDataSource(dataSource);
		factory.afterPropertiesSet();
		return factory.getObject();
	}
}

Creating JPA Repository Class

Create below JPA repository interface that extends spring JpaRepository interface to get advantages of the spring built-in functionalities.

package com.jeejava.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.jeejava.entity.Region;

public interface RegionRepository extends JpaRepository<Region, Integer> {
}

Creating Service Class

This service is responsible for fetching data from JPA repository and performing any business logic if required and communicates with controller.

The below service class gets all regions from the data layer and process any business logic and finally sends to controller layer.

package com.jeejava.service;

import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.jeejava.entity.Region;
import com.jeejava.repository.RegionRepository;

@Service
public class RegionService {
	@Resource
	private RegionRepository regionRepository;
	public List<Region> getRegions() {
		return regionRepository.findAll();
	}
}

Creating Spring REST Controller Class

The following REST controller class is responsible for handling request and response with clients.

This spring REST controller will send region data to the clients. Ideally we should not use entity class in the ResponseEntity of the REST controller instead we should use DTO class but for simplicity I have used here entity class.

package com.jeejava.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jeejava.entity.Region;
import com.jeejava.service.RegionService;

@RestController
public class RegionController {
	@Autowired
	private RegionService regionService;
	@GetMapping("/regions")
	public ResponseEntity<List<Region>> getRegions() {
		List<Region> regions = regionService.getRegions();
		return new ResponseEntity<List<Region>>(regions, HttpStatus.OK);
	}
}

Creating Main Class

Create below main class to startup the Spring Boot application example Spring EnableEncryptableProperties with Jasypt (Java simplified encryption).

You need to scan the base packages to let spring know where you have put all of your controller, service, repository, entity, configuration classes.

package com.jeejava.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.jeejava")
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

Testing the Application

Once your application is up and running you can access the following URL to fetch regions from the tables using the below URL:

http://localhost:9999/regions

You can test using Postman, REST client or even using browser as it is GET request. You would get all available regions from the table in JSON format.

That’s all. hope you got idea how to use Jasypt (Java simplified encryption) by going through example Spring EnableEncryptableProperties with Jasypt (Java simplified encryption).

You may also like to read:

Batch Insert using Spring JdbcTemplate

Transaction Management in Spring

Hibernate UserType using Spring Data JPA

Spring Data JPA Batch Insertion

Spring Data JPA Entity Auditing using EntityListeners

Spring Data JPA Entity Graph

Spring Data JPA CRUD Example

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials Twitter Facebook  Google Plus Linkedin Or Email Me

Leave a Reply

Your email address will not be published. Required fields are marked *