Spring Security Filter 学习笔记
过滤器可以简单理解成用于拦截请求,并执行相应逻辑的代码。
在Spring Security架构中实现过滤器
在SpringSecurity中,可以通过实现 javax.servlet 包中的 Filter接口构造过滤器。
我们通过实现Filter 接口的doFilter() 方法,执行相关逻辑。该方法包含三个参数:
- ServletRequest:表示http请求,可用它获得请求相关信息。
- ServletResponse:表示http响应,可向它添加相关信息,最后传回客户端。
- 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 学习笔记的更多相关文章
- spring security原理-学习笔记1-整体概览
整体概述 运行时环境 Spring Security 3.0需要Java 5.0 Runtime Environment或更高版本. 核心组件 SecurityContextHolder,Securi ...
- spring security原理-学习笔记2-核心组件
核心组件 AuthenticationManager,ProviderManager和AuthenticationProvider AuthenticationManager只是一个接口,实际中是如何 ...
- Find security bugs学习笔记V1.0
Find security bugs学习笔记V1.0 http://www.docin.com/p-779309481.html
- Spring Security Filter详解
Spring Security Filter详解 汇总 Filter 作用 DelegatingFilterProxy Spring Security基于这个Filter建立拦截机制 Abstract ...
- spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)
绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...
- Spring源码学习笔记9——构造器注入及其循环依赖
Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
随机推荐
- 洛谷 P7450 - [THUSCH2017] 巧克力(斯坦纳树+随机化)
洛谷题面传送门 9.13 补之前 8.23 做的题,不愧是鸽子 tzc( 首先我们先来探讨一下如果 \(c_{i,j}\le k\) 怎么做,先考虑第一问.显然一个连通块符合条件当且仅当它能够包含所有 ...
- [USACO17FEB]Why Did the Cow Cross the Road III P
[USACO17FEB]Why Did the Cow Cross the Road III P 考虑我们对每种颜色记录这样一个信息 \((x,y,z)\),即左边出现的位置,右边出现的位置,该颜色. ...
- 洛谷 P3783 - [SDOI2017]天才黑客(前后缀优化建图)
题面传送门 神仙题一道. 首先注意到这里的贡献涉及到边的顺序,并且只与相邻的边是什么有关,因此不难想到一个做法--边转点,点转边,具体来说对于每条边 \(e\),我们将其拆成两个点 \(in_e,ou ...
- fluidity详解
fluidity详解 1.fluidity编译过程 1.1.femtools库调用方法 编译fluidity/femtools目录下所有文件,打包为libfemtools.a静态库文件: 通过-lfe ...
- 根据VCF构建进化树
VCF2Dis,是一款计算根据vcf文件计算距离矩阵的小工具 1 安装 下载后 tar -zxvf VCF2DisXXX.tar.gz cd VCF2DisXXX make # 添加环境变量即可 2 ...
- 【讲座】朱正江——基于LC-MS的非靶向代谢组学
本次课程主题为<基于LC-MS的非靶向代谢组学>,主要分为代谢组学简介.代谢组学技术简介.非靶向代谢组学方法和数据采集.非靶向代谢组学数据分析和代谢物结构鉴定几个方面. 一.代谢组简介 基 ...
- Mysql索引数据结构详解(1)
慢查询解决:使用索引 索引是帮助Mysql高效获取数据的排好序的数据结构 常见的存储数据结构: 二叉树 二叉树不适合单边增长的数据 红黑树(又称二叉平衡树) 红黑树会自动平衡父节点两边的 ...
- 【2021赣网杯web(一)】gwb-web-easypop
源码分析 <?php error_reporting(0); highlight_file(__FILE__); $pwd=getcwd(); class func { public $mod1 ...
- 寻找pair
给定n个整数使其两两组合成一对pair,例如给定 1 ,2 可以组成的pair为(1,1),(1,2),(2,1),(2,2),然后在这些pair中寻找第k小的pair. 输入第一行包含两个数字,第一 ...
- Docker学习(五)——Docker仓库管理
Docker仓库管理 仓库(Repository)是集中存放镜像的地方. 1.Docker Hub 目前Docker官方维护了一个公共仓库Docker Hub.大部分需求都可以通过 ...