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
相关产品推荐
相关产品推荐

