You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 03:42:14