Spring Security移除WebSecurityConfigurerAdapter后密码校验异常
问题原因
当前基于组件的Spring Security配置中,虽然单独注册了BCryptPasswordEncoder类型的Bean和PersonDetailsService类型的Bean,但没有将二者绑定到负责用户名密码认证的DaoAuthenticationProvider上。此时框架自动生成的认证提供者会使用默认的明文等值比对逻辑校验密码:直接拿用户提交的密码字符串和数据库存储的字段值做相等判断,因此会出现输入明文密码校验失败、直接输入数据库存储的加密密文反而登录成功的现象。
旧的继承WebSecurityConfigurerAdapter的写法中,通过auth.userDetailsService(personDetailsService).passwordEncoder(getPasswordEncoder())显式完成了UserDetailsService和PasswordEncoder的绑定,因此认证逻辑正常。
修复方法
不需要回退到已废弃的适配器配置方式,只需在SecurityConfig中显式声明绑定了两个组件的DaoAuthenticationProviderBean即可,修改后的SecurityConfig代码如下:
@EnableWebSecurity public class SecurityConfig { private final PersonDetailsService personDetailsService; private final PasswordEncoder passwordEncoder; public SecurityConfig(PersonDetailsService personDetailsService, PasswordEncoder passwordEncoder) { this.personDetailsService = personDetailsService; this.passwordEncoder = passwordEncoder; } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests().antMatchers("/auth/login", "/error", "/auth/registration").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/auth/login") .loginProcessingUrl("/process_login") .defaultSuccessUrl("/hello", true) .failureUrl("/auth/login?error") .and() .logout().logoutUrl("/logout").logoutSuccessUrl("/auth/login"); return http.build(); } @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(personDetailsService); provider.setPasswordEncoder(passwordEncoder); return provider; } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
补充说明
- Spring Security表单登录的密码校验逻辑由
DaoAuthenticationProvider承载,必须显式为其指定用户查询服务和密码编码器,否则会走默认的明文比对逻辑 - Spring Security 5.7+版本废弃
WebSecurityConfigurerAdapter后,推荐通过注册独立Bean的方式完成认证组件的配置,显式声明DaoAuthenticationProvider是官方推荐的绑定UserDetailsService和PasswordEncoder的方式,不需要额外调用AuthenticationConfiguration的旧链式方法
内容的提问来源于stack exchange,提问作者Nikita Kordyuk
相关产品推荐
相关产品推荐

