azerphoenix
@azerphoenix
Java Software Engineer

Почему при сравнении 2-х хешей BCryptPasswordEncoder они могут не совпадать?

Здравствуйте!
Довольно странная штука... Раньше все работало, а сейчас работает некорректно. Есть простая форма регистрации и я использую BCryptPasswordEncoder для пароля.

Соответственно, вот минимальный код для работы:
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";
}


Суть в том, что если пользователь изменил пароль, то сравниваю 2 хэша и соответственно либо обновляю пароли, либо нет. И тут почему-то метод matches() возвращает false и соответственно, пароль обновляется, даже когда пользователь его не обновлял.

Хэш, который хранится в БД:
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.

Хэш, который отображается в поле пароль на фронте:
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.

Хэш, котоый передается POSTом
$2a$10$Qx1zgFOWqlTkpSUI0pb5CuQzFnwIq3wxNyn.tjk8NT6kmrZAN3Lv.


А вот, почему так, пока не пойму... Что самое интересное, раньше работало. Заранее благодарю за идеи по устранению проблемы)
  • Вопрос задан
  • 1579 просмотров
Решения вопроса 1
saboteur_kiev
@saboteur_kiev
software engineer
if(!encoder.matches(password, user.getPassword())) {
        user.setPassword(passwordEncoder.encode(password));
    }

Я верно понимаю, что строку полученную от юзера (пароль) вы напрямую сравниваете с тем, что у вас хранится в базе (хеш пароля)?
Может быть надо :

if(!encoder.matches(passwordEncoder.encode(password), user.getPassword())) {
        user.setPassword(passwordEncoder.encode(password));
    }
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@IchBinImmerFertig
У меня была проблема в том, что при смены роли юзера менялся и пароль сам. Вот это помогло

if (!user.getPassword().equals(userService.getById(user.getId()).getPassword())){
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы