Spring Security过滤器链加载执行流程源码解析

针对Spring Security过滤器链加载执行流程源码解析的完整攻略,我把它分为以下几个部分:

  1. 概述
  2. Spring Security过滤器链的加载流程
  3. Spring Security过滤器链的执行流程
  4. 示例1:启动时访问静态资源
  5. 示例2:访问受保护资源

下面对每个部分进行详细讲解。

1. 概述

Spring Security是一个基于Spring框架的安全框架,提供了身份认证、授权和其他安全功能。Spring Security的核心概念是过滤器链,在过滤器链中会执行多个SecurityFilterChain,每个SecurityFilterChain由一些过滤器组成,过滤器会逐一进行处理。在本篇攻略中,我们将深入分析Spring Security过滤器链的加载流程和执行流程。

2. Spring Security过滤器链的加载流程

Spring Security的过滤器链加载流程如下:

  1. 在WebSecurityConfigurerAdapter中,我们可以通过调用configure(HttpSecurity http)方法来配置过滤器链。在这个方法中,我们可以通过http.authorizeRequests().xxx()等方法来进行配置。
  2. 在configure(HttpSecurity http)方法中,会调用WebSecurity.applyDefaultConfiguration()方法来应用默认配置。这个方法会加载默认的过滤器链。默认过滤器链中有以下几个SecurityFilterChain:
    • SecurityContextHolderAwareRequestFilter:将SecurityContextPersistenceFilter添加到链的头部
    • UsernamePasswordAuthenticationFilter:身份认证过滤器
    • DefaultLoginPageGeneratingFilter:生成默认登录页面过滤器
    • CasAuthenticationFilter:CAS身份认证过滤器
    • ConcurrentSessionFilter:处理并发会话过滤器
    • RequestCacheAwareFilter:请求缓存过滤器
    • SecurityContextPersistenceFilter:安全上下文持久化过滤器
    • LogoutFilter:登出过滤器
    • BasicAuthenticationFilter:基本身份认证过滤器
    • RememberMeAuthenticationFilter:记住我身份认证过滤器
    • AnonymousAuthenticationFilter:匿名身份认证过滤器
  3. 在调用WebSecurity.applyDefaultConfiguration()方法后,会继续调用其他configure()方法来加载自定义的过滤器链。我们可以通过这些方法来添加新的SecurityFilterChain。
  4. 最后,Spring Security会加载所有SecurityFilterChain,并将它们保存在WebSecurity中。

3. Spring Security过滤器链的执行流程

Spring Security的过滤器链执行流程如下:

  1. 当有一个请求到达服务器,会先经过前置过滤器,这些前置过滤器并不属于Spring Security的过滤器链。
  2. 当请求到达Spring Security的过滤器链后,会按照SecurityFilterChain中定义的顺序进行处理。
  3. 在SecurityFilterChain中,每个过滤器中的doFilter()方法会被逐一调用。
  4. 如果某个过滤器中调用了chain.doFilter()方法,则会顺序执行下一个过滤器。
  5. 如果某个过滤器中已经处理完了请求,就会返回到上一个过滤器,逐级向前返回,直到返回到前置过滤器。

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技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • java对同一个文件进行读写操作方法

    要在Java中对同一个文件进行读写操作,我们可以使用Java的File类和I/O流,具体方法如下: 使用File类实例化File对象来代表文件。可以在实例化File对象时指定文件的路径和文件名,例如: File file = new File("path/to/file.txt"); 其中,”path/to/file.txt”应替换为实际…

    Java 2023年5月19日
    00
  • java中out.print和out.write的方法

    让我来为您详细讲解Java中out.print和out.write的方法。 out.print和out.write的方法 在Java中,System.out是一个静态成员变量,它是Java标准输出流的一个对象。通过System.out,我们可以向控制台输出信息。 System.out对象有两个常用的方法:print()和write()。两者的用途相似,但细节…

    Java 2023年5月26日
    00
  • Java下载文件的4种方式总结

    以下是Java下载文件的4种方式总结的详细攻略: 一、通过URL类下载文件 Java中可以通过URL类来下载远程文件,具体步骤如下: 创建一个URL对象,指定远程文件的URL地址; URL url = new URL("http://example.com/file/file.txt"); 打开URL连接; URLConnection c…

    Java 2023年5月20日
    00
  • 浅谈Java中Properties类的详细使用

    接下来我将详细讲解“浅谈Java中Properties类的详细使用”的完整攻略,内容如下: 1. Properties类介绍 Properties类是Java中的一个集合类,它继承了Hashtable类,并且具有以下特点: 它用于表示一组属性,属性的值可以是字符串 Properties对象通常用来存储配置文件中的键值对数据,也可以序列化到文件中或从文件中进行…

    Java 2023年6月15日
    00
  • Java实现英文猜词游戏的示例代码

    Java实现英文猜词游戏的示例代码 简介 英文猜词是一种简单而有趣的游戏。在这个游戏中,计算机会随机选取一个单词,并将其中的字母都用空格代替。玩家需要猜出这个单词是什么,并逐步填充每一个空格。每次猜错都会导致玩家失去一部分生命值,当生命值归零时,游戏结束。 本文将分享如何使用Java来实现这样一个英文猜词游戏。以下是完整的示例代码: import java.…

    Java 2023年5月19日
    00
  • springboot使用Logback把日志输出到控制台或输出到文件

    下面是使用Spring Boot集成Logback将日志输出到控制台或文件的完整攻略。 步骤1: 添加Logback和Spring Boot的依赖 首先需要在pom.xml文件中添加Logback和Spring Boot的依赖: <!– Logback for logging –> <dependency> <groupId…

    Java 2023年5月26日
    00
  • 完美解决java.lang.OutOfMemoryError处理错误的问题

    下面我将详细讲解如何完美解决 java.lang.OutOfMemoryError 错误的处理问题。 什么是 java.lang.OutOfMemoryError 错误? java.lang.OutOfMemoryError 错误是指 Java 应用程序在运行时申请的内存超过了 Java 虚拟机所能分配的最大内存限制,导致 Java 虚拟机耗尽了可用内存造成…

    Java 2023年5月27日
    00
  • 使用JS获取页面上的所有标签

    获取页面上的所有标签是一个常见的任务,我们可以使用JavaScript来完成这个任务。下面是几个步骤,讲解如何使用JS获取页面上的所有标签。 获取Html页面中的所有标签 可以使用 document.getElementsByTagName(‘tagname’) 方法来获取指定标签名的所有标签,其中 tagname 是标签名。例如,以下代码将获取所有的 &l…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部