/spring-boot-thread-local-and-bouncy-castle

Small Spring boot rest project to demostrate how to use Mdc of log4j and Bouncy Castle in Spring boot applications

Primary LanguageJava

spring-boot-thread-local-and-bouncy-castle

This project is a Small Spring boot rest project to demostrate how to use MDC and Bouncy Castle in Spring boot applications

Thread Local in Java and MDC implementation

The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread. Thus, even if two threads are executing the same code, and the code has a reference to a ThreadLocal variable, then the two threads cannot see each other’s ThreadLocal variables.

In this example we are going to create custom String Threadlocal into Spring boot application to demostrate how a Treadlocal class has the same value between request-response servlet lifecycle.

We have created custom servlet filter class named CustomFilter (filter package). This class filter every hhtp call make to the api and add correlationId value into our custom threadlocal class named MyThreadLocal (threadlocal package)

3 tipical layers controller-service-repository was created to log this value to be able to demostrate that it is not neccesary to pass the value between method: this value is stored at the same thread so it is accesible for every layers.

Threadlocal class
Filter class
Service class
Repository class

To be able to run the Spring boot application write inside a terminal mvn spring-boot:run or if you a pro developer and you use intellij run inside the ide. Open you browser and type "http://localhost:8080/person" and your logs will be shown with correlationId value stored inside threadlocal.

Thread Local log class

MDC log4j map

MDC in Log4j allows us to fill a map-like structure with pieces of information that are accessible to the appender when the log message is actually written.

The MDC structure is internally attached to the executing thread in the same way a ThreadLocal variable would be. The pattern of the appender should be obviously changed in order to retrieve the variables stored in the MDC.

So let’s see our Spring boot code to see how to use it inside and Spring boot application. Firs of all we have to store the value in the filter class as the same way as we have done with our Mythreadlocal.

MDC filter class

It is enough to change the conversion pattern, using the %X{} placeholder for each entry contained in the MDC we would like to be logged:

logging.pattern.level=correlationId:[%X{correlationId}] %5p
MDC filter class

Now if we start again our Spring boot application logs will be automatic appended inside log:

MDC filter class

Obviusly values of thread local and MDC are the same between request but MDC make easier to log custom values inside logs.

Bouncy castle and jasypt

Jasypt is a java library which allows the developer to add basic encryption capabilities to his/her projects with minimum effort, and without the need of having deep knowledge on how cryptography works. It will be used to be able to encript/decript properties in our Spring boot project.

Bouncy Castle is a collection of APIs used in cryptography. It includes APIs for both the Java and the C# programming languages. CE stands for Java Cryptography Extension, is the standard api provided by Java for implementing all encryption decryption techniques . The default encryption provider is SunJCE . To know more about SunJCE encryption you can visit the link:- http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html

BouncyCastle is one such provider which offers more cipher suites and algorithms. You can find more info about BouncyCastle https://www.bouncycastle.org/java.html

We are going to use jasypt with bouncy castle provider.Lets see in action how to put together bouncycastle+jasypt+spring-boot:

  1. Step 1: Dowload jce library (Java JCE Unlimited Strength Jurisdiction Policy Filesss) and replace your jdk content (/jdkxxxxx/jre/lib/security ) with this 2 new jars ( local_policy.jar and US_export_policy.jar): http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

    New jce jars
  2. Step 2: Add new provider entry into your java.security file (this file is at the same route at your policies jars /jdkxxxxx/jre/lib/security) To install the provider statically you need to add it as an entry to the java.security file which can be found in $JAVA_HOME/jre/lib/security/java.security for the JRE/JDK you are using. Look for a list of lines with security.provider.X where X is some number. At the bottom of the list add the line:

    security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

    Add new jce provider
  3. Step 3: Download the boncy castle jar from https://www.bouncycastle.org/latest_releases.html and put it into your jdk installation. Add the bouncy castle jar to JAVA_HOME \jre\lib\ext\ bcprov-jdk15on-147.jar.

Bouncy castle jars

In our project we are using jasypt-spring-boot project (https://github.com/ulisesbocchio/jasypt-spring-boot) to make easier the effort to use bouncy castle in Spring boot application. Like every components in Spring boot application encription/decription files will be configured by our application.properties file:

jasypt.encryptor.password=admin
jasypt.encryptor.algorithm=PBEWITHSHA256AND128BITAES-CBC-BC
jasypt.encryptor.keyObtentionIterations=1000
jasypt.encryptor.poolSize=1
jasypt.encryptor.providerName=BC
jasypt.encryptor.saltGeneratorClassname=org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.stringOutputType=base64
Boot Configuration Jassypt

When an encripted property is needed in application we will use jassypt library.Dowload it from http://www.jasypt.org/download.html from sourceforge https://sourceforge.net/projects/jasypt/files/jasypt/jasypt%201.9.2/. Unzip your zip file into any directory of your system. Download bouncy castle’s jar from https://www.bouncycastle.org/latest_releases.html and copy it into lib directory (your unzip directory plus /lib)

In bin directory you will have encript.sh file. Run it with this command:

./encrypt.sh input=admin123 password=admin algorithm=PBEWITHSHA256AND128BITAES-CBC-BC providerClassName=org.bouncycastle.jce.provider.BouncyCastleProvider
Boot Configuration Jassypt

Note: your password must be the same that you have defined in application.properties file

Your output is your property encripted.Put this value in a property and inject it with @Autowired annotation. Your property value will be decripted in automatic way and you could use it.

Encripted property
Encripted property