O
O
Orkhan Hasanli2018-12-11 00:17:31
Java
Orkhan Hasanli, 2018-12-11 00:17:31

Why can't they match when comparing 2 hashes of BCryptPasswordEncoder?

Hello!
Quite a strange thing... Everything used to work, but now it doesn't work correctly. There is a simple signup form and I am using BCryptPasswordEncoder for the password.
Accordingly, here is the minimum code to work:
Spring Security Config

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("SELECT email, password, active FROM users WHERE email=?")
                .authoritiesByUsernameQuery("SELECT email, role FROM users WHERE email=?");
    }

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

@Autowired
PasswordEncoder passwordEncoder;

@PostMapping("/profile")
public String updateProfile(
        @RequestParam String password,
        @RequestParam String email,
        @RequestParam(value = "userRole",required=false) String userRole,
        @AuthenticationPrincipal UserDetails currentUser
) {

    User user = (User) userService.findUserByEmail(currentUser.getUsername());
    user.setEmail(email);

    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    if(!encoder.matches(password, user.getPassword())) {
        user.setPassword(passwordEncoder.encode(password));
    }
    user.setRole(Role.valueOf(userRole)); //todo обновить процесс смены прав пользователя

    userService.updateUser(user.getUser_id(), user);
    return "redirect:/profile?updated";
}

The bottom line is that if the user has changed the password, then I compare 2 hashes and, accordingly, either update the passwords or not. And here, for some reason, the matches() method returns false and, accordingly, the password is updated even when the user has not updated it.
Hash stored in the database:
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.

The hash that is displayed in the password field on the front:
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.

Hash sent by POST
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.

But I don’t understand why this is so, until I understand ... What is most interesting, it used to work. Thank you in advance for any ideas to fix the problem)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Saboteur, 2018-12-11
@azerphoenix

if(!encoder.matches(password, user.getPassword())) {
        user.setPassword(passwordEncoder.encode(password));
    }

I correctly understand that you directly compare the string received from the user (password) with what you have stored in the database (password hash)?
It may be necessary:
if(!encoder.matches(passwordEncoder.encode(password), user.getPassword())) {
        user.setPassword(passwordEncoder.encode(password));
    }

I
IchBinImmerFertig, 2022-01-27
@IchBinImmerFertig

I had a problem that when changing the role of the user, the password itself also changed. This helped
if (!user.getPassword().equals(userService.getById(user.getId()).getPassword())){
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question