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/ ...
随机推荐
- ROS机器人开发实践1->SSH远程登录要点记录
1.有线网卡 设置 找到有线网络,点击设置,修改其中的IPv4的地址和子网掩码. 1 //地址 2 192.168.xxx.xxx 3 //子网掩码 4 255.255.255.0 点击应用 2.配置 ...
- 『MdOI R1』Treequery
我们可以思考怎么做呢. 首先我们需要进行一些分类讨论: 我们先思考一下如果所有关键点都在 \(p\) 的子树内, 那显然是所有关键点的 \(Lca\) 到 \(p\) 距离. 如果所有关键点一些在 \ ...
- Codeforces 375C - Circling Round Treasures(状压 dp+最短路转移)
题面传送门 注意到这题中宝藏 \(+\) 炸弹个数最多只有 \(8\) 个,故考虑状压,设 \(dp[x][y][S]\) 表示当前坐标为 \((x,y)\),有且仅有 \(S\) 当中的物品被包围在 ...
- 混合(Pooling)样本测序研究
目录 1.混合测序基础 2. 点突变检测 3. BSA 4. BSR 5. 混合样本GWAS分析 6. 混合样本驯化研究 7. 小结 1.混合测序基础 测序成本虽然下降了,但对于植物育种应用研究来说还 ...
- [Linux] 非root安装Lefse软件及其数据分析
说明 Lefse软件是宏组学物种研究常用软件,一般大家用在线版本即可.但要搭建在Linux集群环境中有点烦,记录一下折腾过程. 安装 这个软件是python2写的,因此假设我已经安装好了较高版本的py ...
- perl 子函数传入多个数组
perl中的引用和C中的指针一样,用"\"标识,引用后可使用符号"->"取值.解引用则在对应的数据类型前加$,@ 或%. 这里这里用两数组求和做示例,引用 ...
- linux下面升级 Python版本并修改yum属性信息
最近需要在linux下使用python,故需要升级一下python版本,上网查询了一下相关资料,更新了一下linux下面的python环境,记录如下: linux下面升级 Python版本并修改yum ...
- EXCEL-如何在excel中对图片进行批量排版
新建EXCEL->导入图片->如果每张图高度为33个单元格,共计10张图,那么将最后边的那张图(即正对着你的那一张)剪切粘贴到33*9行第一个单元格处->按F5定位"对象& ...
- 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本身的问题 根据 ...
- [Windows编程]模块遍历
模块遍历 整体思路 1.创建进程快照 2.遍历首次模块 3.继续下次遍历 4.模块信息结构体 相关API的调用 创建进程快照API HANDLE WINAPI CreateToolhelp32Snap ...