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

2022年Spring Boot认证:WebSecurityConfigurerAdapter弃用后基础认证咨询

Spring Security 弃用WebSecurityConfigurerAdapter后的基础认证实现

核心原理

Spring Security的认证核心是 Servlet 过滤器链机制:客户端请求进入应用后,会按顺序经过链上的多个认证过滤器,过滤器提取请求携带的身份凭证(比如表单提交的用户名密码、请求头里的token),交给AuthenticationManager完成凭证校验,校验通过后将认证通过的用户身份信息存入SecurityContext,后续的授权校验、接口获取用户信息都直接从这个上下文读取数据。

WebSecurityConfigurerAdapter被弃用的核心原因是Spring团队希望用户转向组件化的Bean注入方式配置安全逻辑,避免继承带来的僵化配置问题,所有原来通过重写父类方法实现的配置,都可以通过直接注入对应类型的Spring Bean完成。


可直接运行的基础实现案例

以下代码兼容Spring Boot 2.7.x、3.x版本,完全不使用已弃用的WebSecurityConfigurerAdapter。

1. 引入基础依赖

<dependencies>
    <!-- Web 核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring Security 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

2. 核心安全配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity // 开启方法级权限控制,替代旧版@EnableGlobalMethodSecurity
public class BasicSecurityConfig {

    /**
     * 配置接口拦截规则、登录方式,替代原Adapter中重写configure(HttpSecurity)的逻辑
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        // 配置公开放行的路径,不需要登录即可访问
                        .requestMatchers("/public/**", "/error").permitAll()
                        // 其余所有请求都要求认证后访问
                        .anyRequest().authenticated()
                )
                // 开启默认表单登录页
                .formLogin(withDefaults())
                // 开启HTTP Basic认证(适合接口调试、前后端分离简单场景)
                .httpBasic(withDefaults())
                // 临时关闭csrf,方便本地调试,生产环境根据场景开启
                .csrf(csrf -> csrf.disable());
        return http.build();
    }

    /**
     * 密码编码器,Spring Security强制要求所有存储的密码必须经过哈希编码,禁止明文存储
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 用户信息加载逻辑,替代原Adapter中配置用户详情的逻辑
     * 这里用内存存储做演示,生产环境只需要实现UserDetailsService接口,从数据库读取用户信息即可
     */
    @Bean
    public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails commonUser = User.withUsername("user")
                .password(passwordEncoder.encode("123456"))
                .roles("USER")
                .build();
        UserDetails adminUser = User.withUsername("admin")
                .password(passwordEncoder.encode("admin123"))
                .roles("ADMIN", "USER")
                .build();
        return new InMemoryUserDetailsManager(commonUser, adminUser);
    }

    /**
     * 认证管理器,自定义登录逻辑(比如验证码登录、手机号登录)时需要用到,按需注入即可
     */
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(userDetailsService(passwordEncoder()))
                .passwordEncoder(passwordEncoder())
                .and()
                .build();
    }
}

3. 测试接口

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    // 公开接口,不需要登录
    @GetMapping("/public/hello")
    public String publicEndpoint() {
        return "公开接口返回内容,无需认证";
    }

    // 登录即可访问
    @GetMapping("/user/profile")
    public String userProfile() {
        return "登录用户可见的个人信息";
    }

    // 仅管理员角色可访问
    @GetMapping("/admin/dashboard")
    @PreAuthorize("hasRole('ADMIN')")
    public String adminDashboard() {
        return "管理员可见的后台数据";
    }
}

迁移避坑要点

  • 旧教程里的antMatchers()方法在Spring Boot 3.x/Spring Security 6.x中已移除,统一使用requestMatchers()配置路径规则,2.7.x版本两个方法兼容
  • 不要手动实例化PasswordEncoder,统一从Spring容器获取,避免不同实例哈希规则不一致导致密码校验失败
  • 配置方法级权限时不要再用已过时的@EnableGlobalMethodSecurity,直接用@EnableMethodSecurity即可,默认开启@PreAuthorize、@PostAuthorize注解支持
  • 内存用户仅适合本地测试,生产环境替换为自定义UserDetailsService实现,从数据库查询用户信息即可,其余配置逻辑不需要改动

启动项目后,访问/public/hello可以直接拿到返回内容,访问/user/profile会自动跳转到Spring Security默认登录页,使用配置的账号密码(比如user/123456)登录后即可访问,普通用户访问/admin/dashboard会返回403无权限,admin账号登录后可正常访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:39:18