过滤器可以简单理解成用于拦截请求,并执行相应逻辑的代码。

在Spring Security架构中实现过滤器

在SpringSecurity中,可以通过实现 javax.servlet 包中的 Filter接口构造过滤器。

我们通过实现Filter 接口的doFilter() 方法,执行相关逻辑。该方法包含三个参数:

  1. ServletRequest:表示http请求,可用它获得请求相关信息。
  2. ServletResponse:表示http响应,可向它添加相关信息,最后传回客户端。
  3. FilterChain:表示过滤链,用于把请求和响应转发到过滤链上的下一个过滤器。

Spring Security为我们提供了一些过滤器实现,例如:

  • BasicAuthenticationFilter:用于http认证。
  • CsrfFilter:用于跨请求保护。
  • CorsFilter:负责跨域资源共享 (CORS) 授权规则。

多个过滤器集合在一起形成一条过滤链,它们之间有一定顺序。你可以通过存在于过滤链上的一个过滤器,在它的相对位置添加一个新的过滤器。

在过滤链上的一个过滤器前面,添加一个新的过滤器

可以通过下面的方法在某过滤器前面添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class);
} }

CustomFilter是你自定义实现的过滤器类,BasicAuthenticationFilter是认证过滤器的默认类型。

在过滤链上的一个过滤器后面,添加一个新的过滤器

下面的代码是在某过滤器后面添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
} }

在过滤链上的一个过滤器位置,添加一个新的过滤器

下面代码是在一个过滤器的位置上,添加一个新的过滤器。

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(HttpSecurity http) throws Exception {
http..addFilterAt(new CustomFilter(), BasicAuthenticationFilter.class);
} }

当在一个过滤器的位置上,加入一个新的过滤器,Spring Security不会假设该位置上只有一个过滤器, 它也不会保证该位置上过滤器的顺序。

Spring Security 提供的过滤器实现

Spring Security 提供了一些实现Filter借口的抽象类,并在里面加入一些功能。你可以通过继承这些类来构建过滤器类。例如OncePerRequestFilter等。由于Spring Security不能保证一个过滤器对于同一个请求不会被调用多次,我们可以是过滤器继承OncePerRequestFilter来保证。

演示代码

在过滤器BasicAuthenticationFilter的前面、当前位置、后面各添加一个新的过滤器。

创建一个SpringBoot项目,它的依赖如下:

    <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

创建三个过滤器,分别为BeforeFilter、CurrentFilter、AfterFilter。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class BeforeFilter implements Filter { @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("BeforeFilter: " + "在其前面插入的过滤器");
chain.doFilter(request, response);
} }
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class CurrentFilter implements Filter { @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("CurrentFilter: " + "在其当前位置插入的过滤器");
chain.doFilter(request, response);
} }
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class AfterFilter implements Filter { @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("AfterFilter: " + "在其后面插入的过滤器");
chain.doFilter(request, response);
} }

创建一个配置类ProjectConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import hookind.security009.filter.AfterFilter;
import hookind.security009.filter.BeforeFilter;
import hookind.security009.filter.CurrentFilter; @Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
// 在前面加入一个过滤器
http.addFilterBefore(new BeforeFilter(), BasicAuthenticationFilter.class);
// 在当前位置加入一个过滤器
http.addFilterAt(new CurrentFilter(), BasicAuthenticationFilter.class);
// 在其后面加入一个过滤器
http.addFilterAfter(new AfterFilter(), BasicAuthenticationFilter.class);
}
}

创建一个Controller类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class HelloController { @GetMapping("/hello")
public String hello(){
return "Hello";
}
}

启动程序后,在浏览器输入网址 http://localhost:8080/hello,我的控制台输出如下:

BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器
BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器
BeforeFilter: 在其前面插入的过滤器
CurrentFilter: 在其当前位置插入的过滤器
AfterFilter: 在其后面插入的过滤器

由上可知,过滤器是按BeforeFilter、CurrentFilter、AfterFilter顺序调用的。也表示,对于同一个请求,Spring Security可能会调用同一个过滤器多次。

Spring Security Filter 学习笔记的更多相关文章

  1. spring security原理-学习笔记1-整体概览

    整体概述 运行时环境 Spring Security 3.0需要Java 5.0 Runtime Environment或更高版本. 核心组件 SecurityContextHolder,Securi ...

  2. spring security原理-学习笔记2-核心组件

    核心组件 AuthenticationManager,ProviderManager和AuthenticationProvider AuthenticationManager只是一个接口,实际中是如何 ...

  3. Find security bugs学习笔记V1.0

    Find security bugs学习笔记V1.0 http://www.docin.com/p-779309481.html

  4. Spring Security Filter详解

    Spring Security Filter详解 汇总 Filter 作用 DelegatingFilterProxy Spring Security基于这个Filter建立拦截机制 Abstract ...

  5. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)

    绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...

  6. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

  7. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  8. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  9. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

随机推荐

  1. ROS机器人开发实践1->SSH远程登录要点记录

    1.有线网卡 设置 找到有线网络,点击设置,修改其中的IPv4的地址和子网掩码. 1 //地址 2 192.168.xxx.xxx 3 //子网掩码 4 255.255.255.0 点击应用 2.配置 ...

  2. 『MdOI R1』Treequery

    我们可以思考怎么做呢. 首先我们需要进行一些分类讨论: 我们先思考一下如果所有关键点都在 \(p\) 的子树内, 那显然是所有关键点的 \(Lca\) 到 \(p\) 距离. 如果所有关键点一些在 \ ...

  3. Codeforces 375C - Circling Round Treasures(状压 dp+最短路转移)

    题面传送门 注意到这题中宝藏 \(+\) 炸弹个数最多只有 \(8\) 个,故考虑状压,设 \(dp[x][y][S]\) 表示当前坐标为 \((x,y)\),有且仅有 \(S\) 当中的物品被包围在 ...

  4. 混合(Pooling)样本测序研究

    目录 1.混合测序基础 2. 点突变检测 3. BSA 4. BSR 5. 混合样本GWAS分析 6. 混合样本驯化研究 7. 小结 1.混合测序基础 测序成本虽然下降了,但对于植物育种应用研究来说还 ...

  5. [Linux] 非root安装Lefse软件及其数据分析

    说明 Lefse软件是宏组学物种研究常用软件,一般大家用在线版本即可.但要搭建在Linux集群环境中有点烦,记录一下折腾过程. 安装 这个软件是python2写的,因此假设我已经安装好了较高版本的py ...

  6. perl 子函数传入多个数组

    perl中的引用和C中的指针一样,用"\"标识,引用后可使用符号"->"取值.解引用则在对应的数据类型前加$,@ 或%. 这里这里用两数组求和做示例,引用 ...

  7. linux下面升级 Python版本并修改yum属性信息

    最近需要在linux下使用python,故需要升级一下python版本,上网查询了一下相关资料,更新了一下linux下面的python环境,记录如下: linux下面升级 Python版本并修改yum ...

  8. EXCEL-如何在excel中对图片进行批量排版

    新建EXCEL->导入图片->如果每张图高度为33个单元格,共计10张图,那么将最后边的那张图(即正对着你的那一张)剪切粘贴到33*9行第一个单元格处->按F5定位"对象& ...

  9. E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing

    解决办法:apt-get update或者apt-get cleanapt-get update 或者 apt-get update --fix-missing问题解析1 source本身的问题 根据 ...

  10. [Windows编程]模块遍历

    模块遍历 整体思路 1.创建进程快照 2.遍历首次模块 3.继续下次遍历 4.模块信息结构体 相关API的调用 创建进程快照API HANDLE WINAPI CreateToolhelp32Snap ...