针对Spring Security过滤器链加载执行流程源码解析的完整攻略,我把它分为以下几个部分:
- 概述
- Spring Security过滤器链的加载流程
- Spring Security过滤器链的执行流程
- 示例1:启动时访问静态资源
- 示例2:访问受保护资源
下面对每个部分进行详细讲解。
1. 概述
Spring Security是一个基于Spring框架的安全框架,提供了身份认证、授权和其他安全功能。Spring Security的核心概念是过滤器链,在过滤器链中会执行多个SecurityFilterChain,每个SecurityFilterChain由一些过滤器组成,过滤器会逐一进行处理。在本篇攻略中,我们将深入分析Spring Security过滤器链的加载流程和执行流程。
2. Spring Security过滤器链的加载流程
Spring Security的过滤器链加载流程如下:
- 在WebSecurityConfigurerAdapter中,我们可以通过调用configure(HttpSecurity http)方法来配置过滤器链。在这个方法中,我们可以通过http.authorizeRequests().xxx()等方法来进行配置。
- 在configure(HttpSecurity http)方法中,会调用WebSecurity.applyDefaultConfiguration()方法来应用默认配置。这个方法会加载默认的过滤器链。默认过滤器链中有以下几个SecurityFilterChain:
- SecurityContextHolderAwareRequestFilter:将SecurityContextPersistenceFilter添加到链的头部
- UsernamePasswordAuthenticationFilter:身份认证过滤器
- DefaultLoginPageGeneratingFilter:生成默认登录页面过滤器
- CasAuthenticationFilter:CAS身份认证过滤器
- ConcurrentSessionFilter:处理并发会话过滤器
- RequestCacheAwareFilter:请求缓存过滤器
- SecurityContextPersistenceFilter:安全上下文持久化过滤器
- LogoutFilter:登出过滤器
- BasicAuthenticationFilter:基本身份认证过滤器
- RememberMeAuthenticationFilter:记住我身份认证过滤器
- AnonymousAuthenticationFilter:匿名身份认证过滤器
- 在调用WebSecurity.applyDefaultConfiguration()方法后,会继续调用其他configure()方法来加载自定义的过滤器链。我们可以通过这些方法来添加新的SecurityFilterChain。
- 最后,Spring Security会加载所有SecurityFilterChain,并将它们保存在WebSecurity中。
3. Spring Security过滤器链的执行流程
Spring Security的过滤器链执行流程如下:
- 当有一个请求到达服务器,会先经过前置过滤器,这些前置过滤器并不属于Spring Security的过滤器链。
- 当请求到达Spring Security的过滤器链后,会按照SecurityFilterChain中定义的顺序进行处理。
- 在SecurityFilterChain中,每个过滤器中的doFilter()方法会被逐一调用。
- 如果某个过滤器中调用了chain.doFilter()方法,则会顺序执行下一个过滤器。
- 如果某个过滤器中已经处理完了请求,就会返回到上一个过滤器,逐级向前返回,直到返回到前置过滤器。
4. 示例1:启动时访问静态资源
下面给出一个示例,来说明Spring Security过滤器链加载和执行的流程。
我们在WebSecurityConfigurerAdapter中添加以下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//配置访问静态资源不要拦截
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**");
}
}
这个配置添加了一个忽略/static/**路径的WebSecurity配置,在加载配置的时候就会加载WebSecurityConfigurerAdapter实例,然后调用configure(WebSecurity web)方法,将忽略的路径加载到WebSecurity里面。
当访问/static/路径下的资源时,请求会经过所有前置过滤器后,到达Spring Security的过滤器链中。在SecurityFilterChain中,会先执行SecurityContextHolderAwareRequestFilter过滤器,然后执行UsernamePasswordAuthenticationFilter过滤器等其他过滤器。
由于/configure(WebSecurity web)方法中的配置,当请求到达SecurityContextHolderAwareRequestFilter过滤器时,会直接返回,不再进行后续的过滤器处理。
5. 示例2:访问受保护资源
我们在定义一个受保护的资源时,需要在configure(HttpSecurity http)方法中添加以下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//配置受保护资源
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
在上面的配置中,我们定义了一个/login路径的登录页面,除此之外,其他资源都是受保护的。在加载配置的时候,会加载WebSecurityConfigurerAdapter实例,然后调用configure(HttpSecurity http)方法进行配置。在这个方法中,我们可以通过http.authorizeRequests().xxx()等方法来进行配置。
当访问受保护的资源时,请求会经过所有前置过滤器后,到达Spring Security的过滤器链中。在SecurityFilterChain中,会先执行SecurityContextHolderAwareRequestFilter过滤器,然后执行UsernamePasswordAuthenticationFilter过滤器等其他过滤器。
当到达UsernamePasswordAuthenticationFilter过滤器时,Spring Security会检查用户是否已经登录,如果未登录,就会跳转到配置的/login路径的登录页面,等用户输入用户名和密码后,再进行登录操作。
在登录成功后,请求会再次经过前置过滤器,进入Spring Security的过滤器链。此时,请求会顺序经过所有过滤器处理,最后到达被受保护的资源。如果请求被允许访问,就会返回请求结果,否则返回拒绝访问的结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security过滤器链加载执行流程源码解析 - Python技术站