Monday, May 7, 2018

Password Encoding in Spring Security using Spring boot & JPA

Password is one of the most sensitive information of user , which we need to secure at our first priority as a developer,

Storing password as a plain text in database can always make a security breach as well as if someone get the access of database , he/she will be able to see the plain text of password , Its always recommended to store password in encrypted form or in array byte so that a normal person can't able to understand password.
In this article we will see how we can encrypt simply the password in spring boot using spring boot inbuild library.

So lets start


Implementation : (you can download it from GitHub as well)

We first create the project start.spring.io

Now we will see  project structure

we will now see the pom.xml and see all the dependencies we have added
<?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.programinjava.learn</groupId>
	<artifactId>PasswordEncodingInSpringBoot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>PasswordEncodingInSpringBoot</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.12.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

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

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-jwt</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

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


</project>

Here we have used the BCryptPasswordEncoder which is provided by spring security
  1. How to encode the password 
We have added the @Bean in Service class of User.
package com.programinjava.learn.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.programinjava.learn.model.User;
import com.programinjava.learn.repository.UserRepository;

@Service
public class UserService {
	
	@Autowired
	UserRepository userRepository;
	@Bean
	public PasswordEncoder getEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	
	
	public User save(User user) {
//		Encoding the password
		user.setPassword(getEncoder().encode(user.getPassword()));
		return userRepository.save(user);
		
		
	}
	
	
//	this method is for match the password with entered one
	public boolean matchDbPasswordWithEntered(String username,String enteredPassword) {
		
		User user  = userRepository.findByUsername(username);
		if(user == null)
			throw new UsernameNotFoundException("user not found");
		if(getEncoder().matches(enteredPassword,user.getPassword())) {
			System.out.println("Password Match");
//			can change the passwrod as well and store in db
			return true;
		}else {
//			can throw the exception
			System.out.println("Password not matched");
			return false;
		}
	}
	
	

}
Here are are actually below saving the user to database , encoding the password .

2. How to Match the entered password with encrypted password stored in db.
public boolean matchDbPasswordWithEntered(String username,String enteredPassword) {
		
		User user  = userRepository.findByUsername(username);
		if(user == null)
			throw new UsernameNotFoundException("user not found");
		if(getEncoder().matches(enteredPassword,user.getPassword())) {
			System.out.println("Password Match");
//			can change the passwrod as well and store in db
			return true;
		}else {
//			can throw the exception
			System.out.println("Password not matched");
			return false;
		}
	}

In this we are using matches() of Password Encoder.
That it ,
One more thing we have added the encoder in the Server config as well (see the github link)
 @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService)
//              .passwordEncoder(new ShaPasswordEncoder(encodingStrength));
      			.passwordEncoder(getEncoder());
   }
this is used for checking authentication of current user , with the help of its role.

Now Hit the Rest API and see the password in database

Here we can see the Response Status is 201 ( which shows that the user is stored in db)

Now let see the DB row.

Here you can see the Password is encoded . which is quiet secure as compare to plain text.

Also Read:
  1. Spring Boot and Hibernate Tutorials - Application using Spring Boot
  2. What is Spring boot ?
  3. How to read value from property file in spring boot ?
  4. First Rest API Application - Top Spring Framework Interview Questions
  5. Implementation of Swagger in Spring boot
  6. How to use h2 database in spring boot
Thanks for reading 

0 comments:

Post a Comment