Spring Security 的安全模型核心之一是一系列过滤器,这些过滤器组成了一个链。这个过滤器链负责处理进入应用的每个HTTP请求,实现认证、授权等安全功能。每个过滤器都有其特定的责任,它们按照特定的顺序执行。
过滤器链概念
在 Spring Security 中,过滤器链是通过 FilterChainProxy
类来管理的。FilterChainProxy
包含多个 SecurityFilterChain
实例,每个 SecurityFilterChain
包含一系列的过滤器。当一个请求到来时,FilterChainProxy
会根据请求的URL决定使用哪一个 SecurityFilterChain
,然后依次执行该链中的过滤器。
核心过滤器
Spring Security 中的几个关键过滤器包括:
SecurityContextPersistenceFilter
: 保持安全上下文(SecurityContext)在请求之间的持久化。通常用于从Session中加载和存储安全上下文。UsernamePasswordAuthenticationFilter
: 处理基于表单的登录请求。BasicAuthenticationFilter
: 处理基于HTTP基本认证的请求。ExceptionTranslationFilter
: 捕获安全异常,包括认证失败和访问被拒绝的异常,并根据配置进行相应处理(如重定向到登录页面)。FilterSecurityInterceptor
: 最终的授权决策过滤器,它会在调用目标资源之前检查AccessDecisionManager
是否允许当前用户访问请求的资源。
示例配置
在 Spring Boot 应用中,可以通过继承 WebSecurityConfigurerAdapter
并重写 configure(HttpSecurity)
方法来自定义安全配置,包括过滤器链的配置。以下是一个简单的示例,它演示了如何自定义哪些路径受保护,哪些不受保护:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll() // 允许所有人访问"/"和"/home"
.anyRequest().authenticated() // 除了上面定义的URL外,所有请求都需要认证
.and()
.formLogin() // 启用表单登录
.loginPage("/login") // 自定义登录页面URL
.permitAll() // 允许所有人访问登录页面
.and()
.logout() // 启用注销
.permitAll(); // 允许所有人访问注销页面
}
}
深入源码
在源码中,FilterChainProxy
是整个过滤器链的入口点。它被定义为一个Servlet过滤器,负责委托给配置的 SecurityFilterChain
。FilterChainProxy
的初始化过程中会加载 SecurityConfig
中定义的过滤器和相关配置。
public class FilterChainProxy extends GenericFilterBean {
private List<SecurityFilterChain> filterChains;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 根据请求找到对应的SecurityFilterChain
SecurityFilterChain secChain = getSecurityFilterChain(request);
if (secChain != null) {
secChain.doFilter(request, response, chain);
} else {
// 如果没有找到匹配的FilterChain,继续执行Servlet容器默认的Filter链
chain.doFilter(request, response);
}
}
private SecurityFilterChain getSecurityFilterChain(ServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain;
}
}
return null;
}
}
SecurityFilterChain
的 doFilter
方法会依次调用链中的每个过滤器。每个过滤器执行完毕后,一般会调用 FilterChain
的 doFilter
方法,将控制权传递给链中的下一个过滤器,直到所有过滤器执行完毕。
这里的源码只是一个简化的视角,实际的实现可能会更复杂,因为涉及到的类和接口较多,但基本原理和流程是一致的。通过上述分析,你应该能够获得对 Spring Security 过滤器链如何工作的深入理解。
标签:FilterChainProxy,chain,Spring,request,SecurityFilterChain,32,过滤器,Security From: https://blog.csdn.net/qq_43012298/article/details/136940874