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

升级Spring Boot 2.7替换WebSecurityConfigurerAdapter遇认证异常

升级Spring Boot 2.7(Spring Security 5.7)替换WebSecurityConfigurerAdapter遇到的认证问题

我正尝试将应用升级至Spring Boot 2.7版本,该版本对应的Spring Security为5.7,且WebSecurityConfigurerAdapter已被弃用。

原有可正常运行的代码(基于WebSecurityConfigurerAdapter)

@Configuration
@Profile("local-auth")
class LocalAuth {
    @Bean
    public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(
            PasswordEncoder passwordEncoder) {
        return new WebSecurityConfigurerAdapter() {
            @Override
            public void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.inMemoryAuthentication()
                        .withUser("testuser")
                        .password(passwordEncoder.encode("a"))
                        .authorities(toAuthorities(List.of("SOME_AUTHORITY")));
            }

            private List<? extends GrantedAuthority> toAuthorities(List<String> roles) {
                return roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
            }

            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                        .authorizeRequests(authorizeRequests ->
                                authorizeRequests
                                        .antMatchers("/login", "/actuator/**", "/publico/**").permitAll()
                                        .anyRequest().authenticated()
                        )
                        .formLogin(formLogin -> formLogin.defaultSuccessUrl("http://localhost:4200/app/").permitAll())
                        .logout(logout -> logout.logoutUrl("/logout"))
                        .csrf(AbstractHttpConfigurer::disable);
            }
        };
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

替换后的问题

按照官方指南改用InMemoryUserDetailsManager后,登录表单可正常显示,但登录时提示No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken,日志无详细错误输出;尝试手动配置AuthenticationManager Bean时,应用启动报错Cannot apply org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration$EnableGlobalAuthenticationAutowiredConfigurer@313c3cb to already built object。

正确的替换方案

核心问题是密码格式未符合Spring Security 5的规范,且未遵循新的组件式配置风格,以下是修正后的完整代码:

@Configuration
@Profile("local-auth")
class LocalAuth {

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        // 密码需携带加密算法前缀,让框架识别对应的PasswordEncoder
        UserDetails user = User.withUsername("testuser")
                .password("{bcrypt}" + new BCryptPasswordEncoder().encode("a"))
                .authorities(toAuthorities(List.of("SOME_AUTHORITY")))
                .build();
        return new InMemoryUserDetailsManager(user);
    }

    private List<? extends GrantedAuthority> toAuthorities(List<String> roles) {
        return roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 替换过时的authorizeRequests为authorizeHttpRequests
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/login", "/actuator/**", "/publico/**").permitAll()
                        .anyRequest().authenticated()
                )
                .formLogin(form -> form
                        .defaultSuccessUrl("http://localhost:4200/app/")
                        .permitAll()
                )
                .logout(logout -> logout
                        .logoutUrl("/logout")
                )
                .csrf(csrf -> csrf.disable());
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

关键修正说明

  1. 密码格式规范:
    Spring Security 5要求密码必须携带加密算法前缀(如{bcrypt}),框架才能自动匹配对应的PasswordEncoder进行验证。之前的代码仅存储了加密后的密码但无前缀,导致无法识别加密类型,进而找不到对应的AuthenticationProvider。

  2. 替换过时API:
    authorizeRequests()已被标记为过时,改用authorizeHttpRequests(),契合Spring Security 5.7的新配置风格。

  3. 避免手动构建AuthenticationManager:
    当声明了UserDetailsService和PasswordEncoder的Bean后,Spring Security会自动配置对应的AuthenticationManager和AuthenticationProvider,手动构建会破坏自动配置流程,导致启动报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:54:18