Spring Boot – Password Security with PasswordEncoder

If your application is handling user (and their data) you have to be sure, that the password won´t be transfered or stored in plain text. Spring Boot provides a nice and easy way to handle this, the PasswordEncoder API.

Pre Conditions

Before we start with our encoding example, please setup a little Rest Application that has a user (or any other object with a String that you want to have encoded). Here is a little example to visit if you want to.

User Entity

For this purpose let´s estimate a very simple user entity. Just having three attributes with the corresponding setter and getter.

package com.javadevcorner.user;

import javax.persistence.Entity;
import javax.persistence.Id;

/**
 *
 * @author javadevcorner.com
 */
@Entity
public class User {

    @Id
    private long id; 
    
    private String username;
    private String password;    

    //setter and getter
}

As you can see, the password is still a plain text, stored in a String. PasswordEncoder isn´t a new variable type.

PasswordEncoder

Now we´ll come to the use of the PasswordEncoder.

Maven Dependency

To get the PasswordEncoder available in our code, we need to add the following Maven dependency to our pom.xml.

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-crypto</artifactId>
    <!--Place Version here if not already done by parent-->
</dependency>

If your pom.xml isn´t containing the org.springframework.boot parent you need to add the version of the security dependency by yourself. I recommend to you to use the parent.

Defining PasswordEncoder Implementation

To handle the PasswordEncoder during runtime and to avoid a NullPointerException we need to tell our Spring container which implementation we want to get behind the PasswordEncoder API.
To accomplish this please move to your Startup class (the class that contains your Main method) or any other class that is called during Application start and add the following method

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

On this method, we implement the BCryptPasswordEncoder as the Encoding Algorithm we want to use when calling the PasswordEncoder API. On Application Startup this implementation will be injected in the API.

Storing User

To store some user and to make their password encrypted we need to autowire the PassordEncoder and call its encode method

package com.javadevcorner.user;

import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 *
 * @author javadevcorner.com
 */

@Service
public class UserServiceBean implements UserService {
 
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private UserRepository userRepository;

    //Business Logic in here 


    private void createUser() {
        
        User user1 = new User();
        user1.setId(1);
        user1.setUsername("User1");
        user1.setPassword(passwordEncoder.encode("password"));
        
        User user2 = new User();
        user2.setId(2);
        user2.setUsername("User2");
        user2.setPassword(passwordEncoder.encode("myPassword"));
        
        List<User> users = Arrays.asList(user1, user2);
        userRepository.saveAll(users);
    }
    
}

Retrieving User Data

When we now perform a Rest call to our application to get all user data (Id, username and password) this will look similiar to this.

Conclusion

Now you have a major understanding of

  • what the PasswordEncoder is (not a replacement for a string)
  • how the PasswordEncoder works (via autowiring and the .encode(CharSequence cs) method)
  • and how to invoke it in a Spring Boot Context (by calling the @Bean annotated injecting method on startup)

Thanks for reading and have fun using the PasswordEncoder API.

Feel free to share

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.