11.2 BCrypt Encryption and UserDetailsService Implementation
Passwords must never be stored in plain text in a database. Additionally, we need to bridge Spring Security with the user information stored in the database.
1. PasswordEncoder and BCrypt
BCrypt is a widely used algorithm for password hashing. It provides strong security and automatically generates a Salt to defend against rainbow table attacks.
Registering PasswordEncoder Bean
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
2. UserDetails and UserDetailsService
Interfaces must be implemented so that Spring Security can understand user information.
- UserDetails: An object containing user information such as username, password, and authorities.
- UserDetailsService: A service that retrieves user information from a repository (like a database) and returns
UserDetails.
Example of Custom UserDetailsService Implementation
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByEmail(username)
.map(user -> User.builder()
.username(user.getEmail())
.password(user.getPassword()) // Must be BCrypt hashed in DB
.roles(user.getRole().name())
.build())
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
}
}
3. Password Encryption during Signup
The PasswordEncoder must be used during the user registration process.
public void signup(UserDto dto) {
String encodedPassword = passwordEncoder.encode(dto.getPassword());
User user = User.builder()
.email(dto.getEmail())
.password(encodedPassword)
.role(Role.USER)
.build();
userRepository.save(user);
}
🎯 Key Points
- Passwords must be encrypted using a one-way hash algorithm like BCrypt.
- UserDetailsService acts as the connection point between Spring Security and the database.
- Validate user existence and return a
UserDetailsobject in theloadUserByUsernamemethod.