Spring Security 过滤器注册脉络梳理

yizhihongxing

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 中的过滤器执行顺序如下:

  1. WebAsyncManagerIntegrationFilter:用来将 SecurityContext 中的 SecurityContextHolder 适配到 WebAsyncManager 中,以支持 Spring MVC 的异步处理。
  2. SecurityContextPersistenceFilter:从 HttpSession 中获取已有的 SecurityContext 对象,存入到线程安全的 SecurityContextHolder 中。如果 HttpSession 中没有 SecurityContext 对象,则创建一个新的空对象存入。
  3. HeaderWriterFilter:用来添加一些安全相关的 HTTP Header。
  4. CsrfFilter:用来处理 CSRF(跨站请求伪造)攻击。
  5. UsernamePasswordAuthenticationFilter:用来处理用户名密码认证。
  6. RequestCacheAwareFilter:用来处理缓存当前请求。
  7. SecurityContextHolderAwareRequestFilter:用来获取绑定在 SecurityContextHolder 中的 SecurityContext 信息,并将其设置到 HttpServletRequest 中,以便请求线程中的其他组件可以使用。
  8. AnonymousAuthenticationFilter:用来处理匿名用户的认证。
  9. SessionManagementFilter:用来管理 Session,包括创建、销毁、更新 Session 等操作。
  10. ExceptionTranslationFilter:用来处理异常。
  11. 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技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Java定时器Timer使用方法详解

    Java定时器Timer使用方法详解 在Java中,有时需要在程序中计划执行某些任务,或者需要按照一定的时间间隔来执行任务。在这种情况下,我们可以使用Java的定时器——Timer。 Timer概述 Java中的定时器类是java.util.Timer,它允许您在某个时间后执行某个任务,或者在某个时间间隔后重复执行某个任务。它是线程安全的,因此您可以同时计划…

    Java 2023年5月20日
    00
  • java开发Dubbo负载均衡与集群容错示例详解

    Java开发 Dubbo负载均衡与集群容错示例详解 什么是Dubbo负载均衡? Dubbo负载均衡的作用是在服务提供者节点的集群中,按照一定的策略将客户端请求分发到不同的服务提供者节点上,以达到均衡负载的目的。 Dubbo负载均衡有以下几种策略: 随机(random):按权重随机,多数情况下按照权重比例分配请求。 轮询(roundrobin):按权重轮询,多…

    Java 2023年5月25日
    00
  • Java 数据结构与算法系列精讲之红黑树

    红黑树 简介 红黑树是一种自平衡二叉搜索树,它是被广泛使用的一种数据结构,在计算机领域中用于实现高效的查找、插入和删除操作。其名字的由来是因为每个节点都有一个被标记为红色或黑色的属性,又因为它是二叉搜索树,因此在插入、删除操作后,它会自动调整以保持平衡状态。 红黑树的定义 红黑树最重要的两个属性是: 每个节点或者是黑色,或者是红色。 根节点是黑色。 每个叶节…

    Java 2023年5月26日
    00
  • java代码实现银行管理系统

    Java代码实现银行管理系统攻略 银行管理系统是一个较为复杂的系统,包含了许多业务、功能和数据操作,但使用Java语言实现银行管理系统也不是难事。在本文中,我将通过以下步骤详细讲解如何使用Java代码实现银行管理系统。 第一步:分析业务需求 在编写Java代码之前,我们首先需要了解银行管理系统的业务需求。常见的银行管理系统包括账户管理、存取款、贷款管理、利率…

    Java 2023年5月23日
    00
  • springboot学习之构建简单项目搭建步骤详解

    Spring Boot 学习之构建简单项目搭建步骤详解 介绍 Spring Boot 是一个快速、跨平台、微服务框架,受到了很多 Java 开发者的喜欢。构建一个简单的 Spring Boot 项目并不困难,本篇文章将详细讲解如何搭建一个简单的 Spring Boot 项目。 步骤 以下是构建简单项目所需的步骤: 步骤 1:创建一个新的 Spring Boo…

    Java 2023年5月15日
    00
  • java如何导出insert语句并生成sql脚本

    要导出insert语句并生成sql脚本,我们可以使用Java中的JDBC(Java Database Connectivity)连接数据库并操作数据库。下面是详细的步骤: 加载数据库驱动。 首先需要加载对应的数据库驱动,这里以MySQL数据库为例,使用JDBC驱动名为com.mysql.jdbc.Driver。 Class.forName("com…

    Java 2023年5月20日
    00
  • 批量将现有Jar包上传到Maven私服

    批量将现有Jar包上传到Maven私服的过程,大致可以分为以下几个步骤: 准备Maven私服 在私服上创建一个Maven仓库,并提前准备好上传Jar包所需要的账户、密码等信息。 准备Jar包 将需要上传的Jar包,统一归纳至一个目录,在这个目录下,我们可以用以下命令将所有Jar包的文件名打印到一个列表文件中: ls *.jar > list.txt 上…

    Java 2023年5月19日
    00
  • js+csss实现的一个带复选框的下拉框

    实现带复选框的下拉框可以通过JS和CSS的协作来实现。以下是一些实现具体步骤和示例说明: 步骤1:HTML结构 在HTML中,首先需要定义一个select元素,然后使用option元素填充下拉框选项。选项上可以添加checkbox元素,让用户可以选择多个选项。 <select id="myDropdown" multiple>…

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