Spring BCryptPasswordEncoder не получается обновить пароль
Решила в учебный проект добавить возможность смены пароля:
@PostMapping("/settings/change-password")
public String changePassword(Model model, Principal principal,
@RequestParam String oldPassword,
@RequestParam String newPassword,
@RequestParam String repeatPassword) {
User user = userService.findByUsername(principal.getName());
model.addAttribute("user", user);
log.info("Encoded old password: {}", encoder.encode(oldPassword));
log.info("Encoded user's password: {}", user.getPassword());
if (!encoder.matches(encoder.encode(oldPassword), user.getPassword())) {
model.addAttribute("oldPasswordErr", "Old password is invalid!");
return "settings";
} else if (!newPassword.equals(repeatPassword)) {
model.addAttribute("repeatPasswordErr", "New passwords aren't equals!");
return "settings";
}
user.setPassword(encoder.encode(newPassword));
userService.saveUser(user);
return "redirect:/settings";
}
Но он не проходит первую проверку - пароли не совпадают (11111111 - пароль)
Логи:
2020-12-28 15:58:27.999 INFO 8656 --- [nio-8082-exec-1] c.n.m.controllers.SettingsController : Encoded old password: $2a$12$NAx6sRYDNGlnVlkJHWXnRupI9F7n5hsuWv69JY39/GoEL.WLUa0xS
2020-12-28 15:58:28.000 INFO 8656 --- [nio-8082-exec-1] c.n.m.controllers.SettingsController : Encoded user's password: $2a$12$xSARB8s66zhzqNJhU.jruuZCmzdjTDZAJLxxG048.EZEY.6x6GCd2
КАК БЫ, думать долго не пришлось - кодирует он их по разному. Хотя везде используется один бин:
//from my class
private PasswordEncoder encoder;
@Autowired
public void setEncoder(PasswordEncoder encoder) {
this.encoder = encoder;
}
----
//from config
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
protected PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(service);
return daoAuthenticationProvider;
}
Может, делаю я что-то не так? Может, есть возможность раскодировать его, и потом сравнить? (в интерфейсе методов раскодировки я не нашла) - хотя при логине все работает корректно
Ответы (1 шт):
Автор решения: ЮрийСПб
→ Ссылка
Метод PasswordEncoder#matches в сигнатуре в именах аргументах показывает, что первым аргументом должен быть некодированный пароль. Т.е. вам надо вот так сравнивать пароль пришедший от юзера с тем, что записан в БД:
encoder.matches(oldPassword, user.getPassword())
