Spring Security 是一个功能强大的安全框架,提供了全面的 Web 安全功能。它的核心之一是过滤器链,用于拦截和处理 Web 请求。本文将详细介绍如何在 Spring Security 中配置和使用过滤器来管理 Web 请求的安全性。
一、Spring Security 过滤器链
Spring Security 使用过滤器链来处理所有进入应用程序的 HTTP 请求。这些过滤器按顺序执行,每个过滤器负责特定的安全功能,如身份验证、授权、会话管理、跨站点请求伪造(CSRF)保护等。
-
核心过滤器:
SecurityContextPersistenceFilter
:从存储中加载SecurityContext
到SecurityContextHolder
。UsernamePasswordAuthenticationFilter
:处理基于表单登录的身份验证。BasicAuthenticationFilter
:处理 HTTP Basic 验证。ExceptionTranslationFilter
:处理安全异常,如访问被拒绝和身份验证失败。FilterSecurityInterceptor
:执行访问决策。
二、配置 Spring Security 过滤器链
要配置 Spring Security 的过滤器链,可以通过扩展 WebSecurityConfigurerAdapter
类并重写 configure
方法来实现。以下是一个示例配置:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // 禁用 CSRF 保护
.authorizeRequests()
.antMatchers("/public/**").permitAll() // 允许所有用户访问 /public 路径
.antMatchers("/admin/**").hasRole("ADMIN") // 仅允许具有 ADMIN 角色的用户访问 /admin 路径
.anyRequest().authenticated() // 其他请求需要认证
.and()
.formLogin()
.loginPage("/login") // 自定义登录页面
.permitAll()
.and()
.logout()
.permitAll();
}
}
三、常见的过滤器配置
-
身份验证:
- 通过
UsernamePasswordAuthenticationFilter
实现表单登录身份验证。 - 通过
BasicAuthenticationFilter
实现 HTTP Basic 验证。
- 通过
-
授权:
- 通过
FilterSecurityInterceptor
配置 URL 级别的访问控制。 - 使用
@PreAuthorize
和@Secured
注解进行方法级别的访问控制。
- 通过
-
会话管理:
- 通过
SessionManagementFilter
管理会话策略,如会话并发控制和会话固定攻击防护。
- 通过
-
跨站点请求伪造(CSRF)保护:
- 默认情况下启用,通过
CsrfFilter
实现。可以通过http.csrf().disable()
禁用 CSRF 保护。
- 默认情况下启用,通过
四、示例代码解析
下面是一个完整的示例,展示了如何配置 Spring Security 来管理 Web 请求的安全性:
配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
说明:
authorizeRequests
:配置 URL 级别的访问控制。/home
和/
路径允许所有用户访问,/admin/**
路径仅允许 ADMIN 角色访问,其他路径需要认证。formLogin
:配置基于表单的登录,指定自定义登录页面。logout
:配置登出功能,允许所有用户访问。configure(AuthenticationManagerBuilder auth)
:配置内存中的用户存储,定义两个用户:user 和 admin。