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

Spring Security弃用WebSecurityConfigurerAdapter后数据库认证配置

解决方案

核心结论

你不需要再保留旧版基于WebSecurityConfigurerAdapter重写configure(AuthenticationManagerBuilder auth)的代码,在新版Spring Security(5.7+正式废弃适配器类)中,基于Bean的组件化配置会自动完成认证提供者的注册。

原因说明

Spring Security 从5.4版本开始就推荐脱离继承适配器的配置方式:只要你将自定义的DaoAuthenticationProvider声明为Spring容器管理的@Bean,Spring Security的自动配置逻辑会自动收集容器中所有AuthenticationProvider类型的Bean,将其注册到全局认证管理器AuthenticationManager中,无需手动通过AuthenticationManagerBuilder添加。

两种可用配置方式

1. 最简配置(推荐)

直接删除ApplicationSecurityConfig中残留的旧版configure方法即可,其余代码无需改动,你已经声明的daoAuthenticationProvider() Bean会被自动识别加载。

修正后精简的安全配置类结构如下:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig {

    private final PasswordEncoder passwordEncoder;
    private final ApplicationUserService userService;

    public ApplicationSecurityConfig(PasswordEncoder passwordEncoder,ApplicationUserService userService) {
        this.passwordEncoder = passwordEncoder;
        this.userService = userService;
    }

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/", "index", "/css/*", "/js/*").permitAll()
                .antMatchers("/api/**").hasRole(STUDENT.name())
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .defaultSuccessUrl("/courses", true)
                    .passwordParameter("password")
                    .usernameParameter("username")
                .and()
                .rememberMe()
                    .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(21))
                    .key("example")
                    .rememberMeParameter("remember-me") 
                .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
                    .clearAuthentication(true)
                    .invalidateHttpSession(true)
                    .deleteCookies("JSESSIONID", "remember-me")
                    .logoutSuccessUrl("/login");
        return http.build();
    }

    // 这个Bean保留,会被自动注册到认证管理器
    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder);
        provider.setUserDetailsService(userService);
        return provider;
    }

    // 直接删除旧的configure(AuthenticationManagerBuilder auth)方法即可
}

2. 显式配置(多认证场景推荐)

如果后续你需要添加多个认证方式(比如短信验证码登录、LDAP认证),或者希望显式指定认证提供者的加载顺序,可以直接在HttpSecurity配置中手动注册Provider,不需要依赖自动收集,配置方式如下:

@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            // 显式注册自定义DAO认证提供者,多个Provider按添加顺序执行认证
            .authenticationProvider(daoAuthenticationProvider())
            .csrf().disable()
            // 后续拦截、登录、登出等配置和之前完全一致
            .authorizeRequests()
            // ... 其余原有配置保持不变
    return http.build();
}

需要修复的代码问题

你当前代码中存在一个会直接导致认证失败的参数顺序错误:FakeApplicationUserDaoService中实例化ApplicationUser时,用户名和密码的传参顺序和类构造函数定义的顺序不匹配。
ApplicationUser构造函数前两个参数顺序为(String password, String username),但你实例化时先传了用户名、后传了密码,需要修正传参顺序:

new ApplicationUser(
        passwordEncoder.encode("password"), // 第一个参数传密码
        "annasmith", // 第二个参数传用户名
        STUDENT.getGrantedAuthorities(),
        true,
        true,
        true,
        true
)
// linda、tom两个用户的实例化传参也需要按这个顺序调整

内容的提问来源于stack exchange,提问作者iank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:18:23