Spring Security 6中BCryptPasswordEncoder注册登录密码不匹配问题
BCrypt密码哈希后登录验证失败问题
我被这个问题困扰许久,查阅大量资料仍未解决。基于Thymeleaf实现用户注册表单,数据提交至控制器后,通过BCryptPasswordEncoder对密码进行哈希处理,再经JPA存入数据库,但登录时始终提示密码错误,无法完成授权。
奇怪的是,若通过在线哈希生成器生成$2y$版本的BCrypt哈希并手动存入数据库,就能正常登录。对比发现应用生成的哈希版本为$2a$,但整个应用仅配置了一个PasswordEncoder Bean。
尝试过指定BCryptVersion.$2Y、改用SHA-256、调整AuthenticationProvider的注入方式,均无法解决注册后无法登录的问题。
相关代码
SecurityConfig
@Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { @Bean public UserDetailsService userDetailsService() { return new UserService(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(auth -> auth .requestMatchers("/", "/css/**", "/js/**", "/images/**", "/candidate/**", "/setup/**").permitAll() .requestMatchers("/chat/**").hasAnyRole("ADMIN","HEAD","USER") .requestMatchers("/users/**").hasAnyRole("ADMIN","HEAD") .requestMatchers("/admin/**").hasAnyRole("ADMIN") .anyRequest().authenticated() ).formLogin((form) -> form .loginPage("/login") .failureUrl("/login?error=true") .defaultSuccessUrl("/cards", true) .permitAll() ).logout((logout) -> logout .logoutUrl("/logout") .logoutSuccessUrl("/login") .deleteCookies("JSESSIONID") .invalidateHttpSession(true) .clearAuthentication(true) ) .build(); } @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService()); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } }
注册表单控制器
@Controller @RequestMapping("/setup") class SetupController { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PasswordEncoder passwordEncoder; @PostMapping("/create") public String setupUser(User user) { try { user.setPassword(passwordEncoder.encode(user.getPassword())); userService.save(user); } catch(Exception e) { System.out.println(e); return "redirect:/setup?error=true"; } return "redirect:/login"; } }
尝试过的配置
指定BCrypt版本为$2Y:
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(BCryptVersion.$2Y); }
调整AuthenticationProvider注入方式:
@Bean @Autowired public AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailsService); provider.setPasswordEncoder(passwordEncoder); return authProvider; }
内容的提问来源于stack exchange,提问作者shalaley
相关产品推荐
相关产品推荐

