I have a simple controller for user authentication:
@RestController
@RequestMapping("/auth")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/login")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest loginRequest) {
try {
LoginResponse loginResponse = userService.login(loginRequest);
return new ResponseEntity<>(loginResponse, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(ResponseHandler.handleLoginResponse(LoginResponseEnums.GENERAL_ERROR, ""), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
And a service for it:
@Service
public class UserServiceImpl implements UserService {
// FIXME: 6/10/2022 Initialize dummy data for H2, remove on prod
@PostConstruct
private void init() {
userRepository.save(new User("[email protected]", "$2a$10$e8xk4HeAkWwK5DwTFNXgN.ijlYEzlJJDUOcCBLZzTQuWFtQyeaXtW"));
userRepository.save(new User("[email protected]", "$2a$10$e8xk4HeAkWwK5DwTFNXgN.ijlYEzlJJDUOcCBLZzTQuWFtQyeaXtW"));
}
private final UserRepository userRepository;
private final AuthenticationProvider authenticationProvider;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final JwtTokenProvider jwtTokenProvider;
@Autowired
public UserServiceImpl(JwtTokenProvider jwtTokenProvider, UserRepository userRepository, AuthenticationProvider authenticationProvider, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userRepository = userRepository;
this.authenticationProvider = authenticationProvider;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.jwtTokenProvider = jwtTokenProvider;
}
public LoginResponse login(LoginRequest loginRequest) {
String email = loginRequest.getEmail();
String password = loginRequest.getPassword();
try {
authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(email, password));
} catch (Exception e) {
return ResponseHandler.handleLoginResponse(LoginResponseEnums.PASSWORD_INCORRECT, "");
}
Optional<User> userByEmail = userRepository.findUserByEmail(email);
if (userByEmail.isPresent()) {
return ResponseHandler.handleLoginResponse(LoginResponseEnums.SUCCESS, jwtTokenProvider.createToken(email));
} else {
return ResponseHandler.handleLoginResponse(LoginResponseEnums.EMAIL_DOES_NOT_EXIST, "");
}
}
}
And AuthenticationProviderBean
@Bean
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
provider.setPasswordEncoder(bCryptPasswordEncoder());
provider.setUserDetailsService(userDetailsService);
return provider;
}
I have a little problem with
try {
authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(email, password));
} catch (Exception e) {
return ResponseHandler.handleLoginResponse(LoginResponseEnums.PASSWORD_INCORRECT, "");
}
When the original password is presented: "123456", authentication provider authenticates a user, but when i present BCrypt encoded password: "$2a$10$e8xk4HeAkWwK5DwTFNXgN.ijlYEzlJJDUOcCBLZzTQuWFtQyeaXtW", it throws: org.springframework.security.authentication.BadCredentialsException: Bad credentials
I want to authenticate user with BCrypt Encoded password, what do i need to change?
I want to authenticate user with this request:
{
"Email": "[email protected]"
"Password": "$2a$10$e8xk4HeAkWwK5DwTFNXgN.ijlYEzlJJDUOcCBLZzTQuWFtQyeaXtW"
}
CodePudding user response:
BCryptPasswordEncoder doesn't work that way. It's matches
method expects clear text password along with previously encoded password