Spring Security 过滤器注册脉络梳理

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日

相关文章

  • JSP页面间传值问题实例简析

    下面是对JSP页面间传值问题实例简析的完整攻略: 1. 问题分析 在使用JSP进行web页面开发的过程中,经常需要使用多个JSP页面来完成相应的业务功能,这时候我们就需要在不同的JSP页面之间传递参数或对象。 JSP页面间传值的情景: 当我们在JSP页面中调用另外一个JSP页面或Servlet时,可能需要将当前页面中的某些数据传递给其它页面或Servlet进…

    Java 2023年6月15日
    00
  • maven报错:Failed to execute goal on project问题及解决

    针对”Maven报错:Failed to execute goal on project”问题,可能导致报错的原因有很多种,但通常表现为类似于以下的错误提示: Failed to execute goal on project xxx: Could not resolve dependencies for project xxx: Failure to fi…

    Java 2023年5月19日
    00
  • Java使用jni清屏功能的实现(只针对cmd)

    下面是关于Java使用JNI清屏功能的实现攻略。 1. 概述 Java中使用JNI可以调用C代码,因此我们可以使用C代码实现一些Java无法直接实现的功能。本文将介绍如何使用JNI实现Java清屏功能(只针对cmd)。 2. 具体实现 2.1 JNI代码 我们需要编写C代码来实现清屏操作。以下是一个简单的C代码示例,可以实现Windows下的清屏操作: #i…

    Java 2023年5月26日
    00
  • Centos8.2云服务器环境安装Tomcat8.5的详细教程

    下面是CentOS 8.2云服务器环境安装Tomcat 8.5的详细步骤: 1. 安装Java JDK Tomcat需要使用Java运行环境,因此需要先安装Java JDK(Java Development Kit)。 1.1. 更新yum源 在安装Java JDK之前,需要先更新yum源,以确保可以正常下载所需软件包。 sudo yum update 1.…

    Java 2023年5月19日
    00
  • JSP常见的文件操作小结

    JSP常见的文件操作小结 在JSP开发中,文件的操作是比较常见的一个任务,下面整理了关于JSP常见文件操作的攻略。 1. 文件的读取 1.1 读取文本文件 读取文本文件的方法非常简单,只需要使用Java IO库中的BufferedReader来读取文件即可。示例如下: <% String fileName = "example.txt&quo…

    Java 2023年6月15日
    00
  • Java输入/输出流体系详解

    Java输入/输出流体系详解 引言 Java的输入/输出流是Java程序中使用频率很高的部分,从文件IO到网络IO,从字节流到字符流,从节点流到处理流,Java的IO体系都非常的强大和灵活。许多初学者在学习Java IO时经常会对Java IO体系的各个部分感到困惑和无从下手。本篇攻略就是希望能够帮助读者理解Java IO体系的各个方面,掌握Java输入/输…

    Java 2023年5月26日
    00
  • 什么是受检异常?

    什么是受检异常? 在Java中,对于可能会导致程序错误的代码,我们有时会在代码中使用异常机制进行处理,使得程序在运行时遇到问题时可以从异常处理代码块中恢复,继续执行后面的程序。而受检异常(Checked Exception)就是其中一种异常类型,它需要在代码中进行显式的处理,否则编译时就会报错。 受检异常的特点 受检异常与非受检异常(Unchecked Ex…

    Java 2023年4月27日
    00
  • jsp 自动编译机制详细介绍

    JSP自动编译机制详细介绍 JavaServer Pages(JSP)是JavaEE中最受欢迎的技术之一。但是,在JSP中使用Java语言时,容易出现编译错误。为了解决这个问题,JSP引入了自动编译机制以确保在JSP文件中使用的Java代码能够正确地编译。 JSP自动编译机制的原理 JSP自动编译机制是通过在运行时动态编译JSP页面来实现的。当请求一个包含J…

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