Spring Security API参考:WebSecurityConfigurerAdapter使用
【免费下载链接】spring-security Spring Security 项目地址: https://gitcode.com/gh_mirrors/spr/spring-security
1. 概述
WebSecurityConfigurerAdapter是Spring Security框架中用于配置Web安全的适配器类(Adapter Class),它实现了WebSecurityConfigurer接口,为开发者提供了一种便捷的方式来定制HTTP请求的安全规则、用户认证(Authentication)和授权(Authorization)机制。在Spring Security 5.7.0之前的版本中,这是配置Web安全的主要方式,尽管在新版本中已推荐使用组件式配置(SecurityFilterChain Bean),但了解其使用方法对于维护旧项目仍具有重要意义。
2. 核心功能与继承关系
2.1 类定义与继承结构
WebSecurityConfigurerAdapter位于org.springframework.security.config.annotation.web.configuration包下,其核心定义如下(伪代码):
public abstract class WebSecurityConfigurerAdapter
implements WebSecurityConfigurer<WebSecurity> {
// 提供默认的安全配置实现
protected void configure(HttpSecurity http) throws Exception {
// 默认配置逻辑
}
// 配置用户认证信息
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 默认认证配置
}
// 配置WebSecurity(全局安全设置)
public void configure(WebSecurity web) throws Exception {
// 默认WebSecurity配置
}
}
2.2 核心方法说明
| 方法签名 | 作用 | 调用时机 |
|---|---|---|
void configure(HttpSecurity http) | 配置HTTP请求级别的安全规则,如URL授权、表单登录、CSRF保护等 | 每个HTTP请求处理前 |
void configure(AuthenticationManagerBuilder auth) | 配置用户认证源,如内存用户、数据库用户、LDAP用户等 | 认证管理器初始化时 |
void configure(WebSecurity web) | 配置全局安全忽略规则,如静态资源免认证访问 | Spring容器启动时 |
3. 基本使用步骤
3.1 继承适配器类
创建自定义安全配置类,继承WebSecurityConfigurerAdapter并使用@EnableWebSecurity注解启用Web安全功能:
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 重写配置方法
}
3.2 配置HTTP安全规则
通过重写configure(HttpSecurity http)方法定义URL访问权限、登录/登出行为等:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 配置URL授权规则
.authorizeRequests()
.antMatchers("/", "/home").permitAll() // 首页和主页允许所有用户访问
.antMatchers("/admin/**").hasRole("ADMIN") // /admin/**路径需要ADMIN角色
.anyRequest().authenticated() // 其他所有请求需要认证
.and()
// 配置表单登录
.formLogin()
.loginPage("/login") // 自定义登录页面URL
.defaultSuccessUrl("/dashboard", true) // 登录成功后跳转页面
.permitAll() // 允许所有用户访问登录页面
.and()
// 配置登出
.logout()
.logoutUrl("/logout") // 登出URL
.logoutSuccessUrl("/login?logout") // 登出成功后跳转页面
.permitAll();
}
3.3 配置用户认证
通过重写configure(AuthenticationManagerBuilder auth)方法配置用户认证信息,支持多种数据源:
3.3.1 内存用户存储(适合开发环境)
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password123") // {noop}表示不加密(仅用于演示)
.roles("USER")
.and()
.withUser("admin")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") // BCrypt加密密码
.roles("ADMIN", "USER");
}
3.3.2 数据库用户存储(适合生产环境)
需配合UserDetailsService和密码编码器(PasswordEncoder)使用:
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
3.4 配置全局忽略规则
通过重写configure(WebSecurity web)方法排除静态资源(如CSS、JS、图片)的安全检查:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/css/**", "/js/**", "/images/**", "/webjars/**");
}
4. 高级配置示例
4.1 集成Spring Boot时的完整配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 注入自定义UserDetailsService
@Autowired
private CustomUserDetailsService userDetailsService;
// 配置密码编码器
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 配置认证管理器
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
// 配置HTTP安全
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // 开发环境可临时禁用CSRF保护(生产环境强烈建议启用)
.authorizeRequests()
.antMatchers("/api/public").permitAll()
.antMatchers("/api/user").hasRole("USER")
.antMatchers("/api/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID");
}
}
4.2 配置方法级安全
结合@EnableGlobalMethodSecurity注解实现方法级别的权限控制:
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@EnableGlobalMethodSecurity(
prePostEnabled = true, // 启用@PreAuthorize和@PostAuthorize注解
securedEnabled = true, // 启用@Secured注解
jsr250Enabled = true // 启用JSR-250注解(如@RolesAllowed)
)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
// 无需额外配置,注解即可生效
}
在控制器方法中使用:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AdminController {
@PreAuthorize("hasRole('ADMIN') and #id > 0")
@GetMapping("/admin/users/{id}")
public String getUserById(Long id) {
return "User info for ID: " + id;
}
}
5. 版本兼容性与迁移指南
5.1 版本变更说明
| Spring Security版本 | WebSecurityConfigurerAdapter状态 | 推荐配置方式 |
|---|---|---|
| 5.6.x及之前 | 可用(默认配置方式) | 继承WebSecurityConfigurerAdapter |
| 5.7.0及之后 | 标记为@Deprecated(不推荐使用) | 组件式配置(SecurityFilterChain Bean) |
| 6.0.0及之后 | 完全移除 | 必须使用组件式配置 |
5.2 从WebSecurityConfigurerAdapter迁移到SecurityFilterChain
Spring Security 5.7+推荐使用组件式配置,通过定义SecurityFilterChain Bean替代继承适配器类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
return http.build();
}
}
6. 常见问题与解决方案
6.1 密码加密与{noop}前缀问题
问题:直接使用明文密码时抛出java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"异常。
原因:Spring Security 5+默认要求所有密码必须使用加密存储,并通过前缀指定加密算法(如{bcrypt}、{noop}等)。
解决方案:
- 开发环境临时使用
{noop}前缀允许明文密码(不推荐生产环境):.withUser("user").password("{noop}password").roles("USER") - 生产环境配置密码编码器:
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
6.2 CSRF保护导致POST请求403错误
问题:启用CSRF保护时,前端表单提交POST请求返回403 Forbidden。
解决方案:在表单中添加CSRF令牌:
<form action="/login" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="text" name="username" />
<input type="password" name="password" />
<button type="submit">登录</button>
</form>
6.3 静态资源被拦截问题
问题:CSS、JS等静态资源无法加载,浏览器控制台报403错误。
解决方案:通过WebSecurity配置忽略静态资源:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/css/**", "/js/**", "/images/**");
}
7. 总结
WebSecurityConfigurerAdapter作为Spring Security历史上重要的配置方式,为开发者提供了直观的安全配置体验。尽管在新版本中已被组件式配置替代,但理解其设计思想和使用方法对于掌握Spring Security的核心原理仍至关重要。在实际项目中,应根据使用的Spring Security版本选择合适的配置方式,并始终遵循安全最佳实践(如密码加密、启用CSRF保护等)。
对于新开发的项目,强烈建议直接采用Spring Security 5.7+推荐的组件式配置(SecurityFilterChain Bean),以获得更好的灵活性和未来兼容性。
【免费下载链接】spring-security Spring Security 项目地址: https://gitcode.com/gh_mirrors/spr/spring-security
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



