Spring Security 是 Spring 框架的子项目,专门用于处理认证与授权相关的安全问题。在 Spring Security 的实现过程中,过滤器是一个核心概念,所有认证和授权都是通过过滤器实现的。因此,了解 Spring Security 过滤器的注册脉络对于学习 Spring Security 至关重要。
Spring Security 过滤器概述
Spring Security 中最重要的过滤器是 FilterChainProxy 过滤器。它是整个 Spring Security 过滤器链的入口点,所有的请求都要经过它。FilterChainProxy 本身不负责认证或授权,它只是委托给下游的过滤器进行处理。下游的过滤器处理请求时,往往需要判断当前用户是否已经认证和授权,并根据判断结果进行响应处理。
FilterChainProxy 过滤器内部维护一个过滤器列表,每个过滤器都被封装成一个 SecurityFilterChain 对象,表示一组过滤器链。同一个 URL 可能会被多个 SecurityFilterChain 匹配,因此 FilterChainProxy 需要依次遍历所有匹配的 SecurityFilterChain,找到第一个能够处理该请求的 SecurityFilterChain,并将其委托给该 SecurityFilterChain 中的第一个过滤器进行处理。如果所有匹配的 SecurityFilterChain 都不能处理该请求,FilterChainProxy 会返回 404 错误。
Spring Security 过滤器链注册
Spring Security 的过滤器链是由多个过滤器组成的。一般情况下,我们不需要手动注册每个过滤器,只需要注册 FilterChainProxy 过滤器即可,因为它会自动加载所有的过滤器。但是,如果我们需要自定义一些过滤器,或者修改过滤器的执行顺序,就需要手动注册过滤器。
Spring Security 中过滤器链的注册是通过实现 WebSecurityConfigurer 接口来实现的,在该接口的 configure 方法中,我们可以通过 HttpSecurity 对象来配置请求的安全性和授权,也可以通过 HttpSecurity 对象来注册过滤器链。
下面是一个简单的示例,演示如何自定义一个过滤器并将其添加到 Spring Security 过滤器链中,以实现处理 RESTFUL API 后缀 .json 的认证和授权功能:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**.json").authenticated()
.anyRequest().permitAll()
.and()
.addFilterBefore(new JsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
上面的配置中,我们将所有 /api/xxx.json 结尾的请求设置为需要认证和授权的请求,同时添加了一个自定义的 JsonAuthenticationFilter 过滤器,它会在 UsernamePasswordAuthenticationFilter 过滤器之前执行。
Spring Security 过滤器的执行顺序
Spring Security 中的过滤器由多个过滤器组成,它们的执行顺序是非常重要的。一般来说,Spring Security 中的过滤器执行顺序如下:
- WebAsyncManagerIntegrationFilter:用来将 SecurityContext 中的 SecurityContextHolder 适配到 WebAsyncManager 中,以支持 Spring MVC 的异步处理。
- SecurityContextPersistenceFilter:从 HttpSession 中获取已有的 SecurityContext 对象,存入到线程安全的 SecurityContextHolder 中。如果 HttpSession 中没有 SecurityContext 对象,则创建一个新的空对象存入。
- HeaderWriterFilter:用来添加一些安全相关的 HTTP Header。
- CsrfFilter:用来处理 CSRF(跨站请求伪造)攻击。
- UsernamePasswordAuthenticationFilter:用来处理用户名密码认证。
- RequestCacheAwareFilter:用来处理缓存当前请求。
- SecurityContextHolderAwareRequestFilter:用来获取绑定在 SecurityContextHolder 中的 SecurityContext 信息,并将其设置到 HttpServletRequest 中,以便请求线程中的其他组件可以使用。
- AnonymousAuthenticationFilter:用来处理匿名用户的认证。
- SessionManagementFilter:用来管理 Session,包括创建、销毁、更新 Session 等操作。
- ExceptionTranslationFilter:用来处理异常。
- FilterSecurityInterceptor:最后一个过滤器,用来进行授权。
我们也可以手动调整过滤器的执行顺序,以满足我们自己的需求。通过下面的示例,我们可以看到如何调整过滤器的执行顺序,这里将 CsrfFilter 过滤器移动到了 UsernamePasswordAuthenticationFilter 过滤器之后:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**.json").authenticated()
.anyRequest().permitAll()
.and()
.addFilterAfter(new JsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(new CsrfFilter(), JsonAuthenticationFilter.class);
}
}
上面的配置中,我们先禁用了 CsrfFilter 过滤器,然后在配置文件中添加了一个新的 JsonAuthenticationFilter 过滤器,将它加到了 UsernamePasswordAuthenticationFilter 过滤器之后,最后将 CsrfFilter 过滤器加到了 JsonAuthenticationFilter 过滤器之后。这样,我们就改变了过滤器的执行顺序,先执行了 JsonAuthenticationFilter 过滤器,然后才执行了 CsrfFilter 过滤器。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security 过滤器注册脉络梳理 - Python技术站