
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: March 27, 2025
In this tutorial, we’ll discuss a critical part of the registration process, password encoding, which is basically not storing the password in plaintext.
There are a few encoding mechanisms supported by Spring Security, and for this tutorial, we’ll use BCrypt, as it’s usually the best solution available.
Most of the other mechanisms, such as the MD5PasswordEncoder and ShaPasswordEncoder, use weaker algorithms and are now deprecated.
We’ll start by defining the simple BCryptPasswordEncoder as a bean in our configuration:
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
Older implementations, such as SHAPasswordEncoder, require the client to pass in a salt value when encoding the password.
BCrypt, however, will internally generate a random salt instead. This is important to understand because it means that each call will have a different result, so we only need to encode the password once.
To make this random salt generation work, BCrypt will store the salt inside the hash value itself. For instance, the following hash value:
$2a$10$ZLhnHxdpHETcxmtEStgpI./Ri1mksgJ9iDP36FmfMdYyVg9g0b2dq
Separates three fields by $:
Also, be aware that the BCrypt algorithm generates a String of length 60, so we need to make sure that the password will be stored in a column that can accommodate it. A common mistake is to create a column of a different length, and then get an Invalid Username or Password error at authentication time.
We’ll use the PasswordEncoder in our UserService to hash the password during the user registration process:
Example 3.1. The UserService Hashes the Password
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
if (emailExist(accountDto.getEmail())) {
throw new EmailExistsException(
"There is an account with that email adress:" + accountDto.getEmail());
}
User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
user.setEmail(accountDto.getEmail());
user.setRole(new Role(Integer.valueOf(1), user));
return repository.save(user);
}
Now we’ll handle the other half of this process and encode the password when the user authenticates.
First, we need to inject the password encoder bean we defined earlier into our authentication provider:
@Autowired
private UserDetailsService userDetailsService;
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
The security configuration is simple:
Finally, we need to reference this auth provider in our security XML configuration:
<authentication-manager>
<authentication-provider ref="authProvider" />
</authentication-manager>
Or, if we’re using Java configuration:
@Configuration
@ComponentScan(basePackages = { "com.baeldung.security" })
@EnableWebSecurity
public class SecSecurityConfig {
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.authenticationProvider(authProvider())
.build();
}
...
}
This brief article continues the Registration series by showing how to properly store the password in the database by leveraging the simple, but very powerful, BCrypt implementation.