Spring Security原理之springSecurityFilterChain
在上篇文章中,已经大概交代了一下三个地方
spring security
启动WebSecurityConfiguration
主要做了两件事情:
1.根据WebSecurityConfigurerAdapter
中配置的信息创建WebSecurity
这个类
2.springSecurityFilterChain()
创建了一个名叫springSecurityFilterChain
的过滤器,然后值得一提的是在调用WebSecurity
的build()
创建过滤器的时候,调用到了WebSecurity
的init()
方法创建了一个HttpSecurity
的对象,这里会根据配置为我们创建过滤器,最后添加到DefaultSecurityFilterChain
过滤器链里面来
1.为什么要说这个类
在前面的文章中我们已经说到所有的过滤器链都添加到了securityFilterChains
这个列表中,后面出现了下面一行代码
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
我们知道FilterChainProxy
的bean的名字叫做springSecurityFilterChain
里面包含了我们的过滤器链
所以我们必须要清楚他的工作原理
2.类的简单说明
2.1变量
2.1.1 filterChains
变量定义
private List<SecurityFilterChain> filterChains
- 里面存储了过滤器链的信息
2.2构造函数
public FilterChainProxy(List<SecurityFilterChain> filterChains) {this.filterChains = filterChains;}
在WebSecurity
的performBuild()
方法中我们对于spring security的配置最后生成的过滤器链设置到filterChains
这个变量中
3.虚拟过滤器链VirtualFilterChain
private static class VirtualFilterChain implements FilterChain {//原始过滤器链,代表了spring 的application context中所有的过滤器连//其实可以参考DelegatingFilterProxyprivate final FilterChain originalChain;//spring security的过滤器链private final List<Filter> additionalFilters;//因为在FilterChainProxy中request和response被封装到HttpFirewall中,所以我们从这里获取请求信息private final FirewalledRequest firewalledRequest;//spring security的过滤器的长度private final int size;//当前执行到的位置private int currentPosition = 0;private VirtualFilterChain(FirewalledRequest firewalledRequest,FilterChain chain, List<Filter> additionalFilters) {this.originalChain = chain;this.additionalFilters = additionalFilters;this.size = additionalFilters.size();this.firewalledRequest = firewalledRequest;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response)throws IOException, ServletException {//表示spring security的过滤器全部执行完成,那么可以执行spring的application context 中的其他的过滤器链了if (currentPosition == size) {if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)+ " reached end of additional filter chain; proceeding with original chain");}// Deactivate path stripping as we exit the security filter chainthis.firewalledRequest.reset();originalChain.doFilter(request, response);}else {//获取当前过滤器执行到的为止currentPosition++;//当前需要执行的过滤器Filter nextFilter = additionalFilters.get(currentPosition - 1);if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)+ " at position " + currentPosition + " of " + size+ " in additional filter chain; firing Filter: '"+ nextFilter.getClass().getSimpleName() + "'");}//执行当前的过滤器nextFilter.doFilter(request, response, this);}}}
4 FilterChainProxy
的doFilter
方法
我们知道FilterChainProxy
已经被注册到application context中,那么就会被DelegatingFilterProxy
执行到自己的doFilter()
方法,然而先没必要想这么多,就把FilterChainProxy
当成我们在web.xml中定义的一个Filter就行,当有请求进来就会去执行doFilter
方法
@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//只是一个存储信息或者说是否已经在执行的标志boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;if (clearContext) {try {request.setAttribute(FILTER_APPLIED, Boolean.TRUE);doFilterInternal(request, response, chain);}finally {SecurityContextHolder.clearContext();request.removeAttribute(FILTER_APPLIED);}}else {doFilterInternal(request, response, chain);}}private void doFilterInternal(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {FirewalledRequest fwRequest = firewall.getFirewalledRequest((HttpServletRequest) request);HttpServletResponse fwResponse = firewall.getFirewalledResponse((HttpServletResponse) response);List<Filter> filters = getFilters(fwRequest);if (filters == null || filters.size() == 0) {if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(fwRequest)+ (filters == null ? " has no matching filters": " has an empty filter list"));}fwRequest.reset();chain.doFilter(fwRequest, fwResponse);return;}VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);vfc.doFilter(fwRequest, fwResponse);}
- 上面这么多行的代码其实我们大概捋顺一下就知道,主要的无非就是当有请求,判断当前过滤器列表里面是否有过滤器,如果没有执行spring application context中的其他的过滤器链,如果有执行一下两行代码
VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);
vfc.doFilter(fwRequest, fwResponse);
- 首先新建了一个虚拟过滤器链,请参考上面的代码
- 其次执行了doFilter()方法
- 根据上面对于
VirtualFilterChain
的源代码注释,我们是可以看到过滤器链是怎样被执行完的。
5.总结
这个类还是比较简单和清晰明了的。没有晦涩的继承关系。到此为止,我们已经了解到了spring security 的一个请求过来为什么会去穿透我们的过滤器,可以说对于spring security的启动,spring security filter chain的组建,我们基本已经了解完成,最后,在默认情况下进行调试,我们看一下我们的默认的过滤器有哪些,也顺便结束这篇文章吧.
默认配置下的过滤器
Spring Security原理之springSecurityFilterChain相关推荐
- Spring Security原理分析
本文来简单的分析下Spring Security 使用原理.在前面的几节中,已经对 Spring Security 有了一个比较全的使用体验了,这节我们简单的介绍下 Spring Security 基 ...
- spring security原理
spring security通过一系列过滤器实现其功能,入口过滤器如下(web.xml): <filter> <filter-name>springSecurityFilte ...
- Spring Security原理与应用
Spring Security是什么 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置 ...
- spring security原理和机制 | Spring Boot 35
- spring security源码分析之一springSecurityFilterChain
1. spring和spring security的集成,配置web.xml如下: <context-param><param-name>contextConfigLocati ...
- Spring Security OAuth2.0认证授权知识概括
Spring Security OAuth2.0认证授权知识概括 安全框架基本概念 基于Session的认证方式 Spring Security简介 SpringSecurity详解 分布式系统认证方 ...
- spring security技术分享
Spring Security技术专题 一.初识认证和授权 1.1 认证 1.2 会话 1.3 授权 1.4 授权的数据模型 1.5 RBAC 1.5.1 角色访问控制 1.5.2 资源访问控制 1. ...
- Spring Security应用详解(集成SpringBoot)
Spring Security应用详解 集成SpringBoot 工作原理 认证流程 授权流程 集成SpringBoot 1.Spring Boot介绍 Spring Boot是一套Spring的快速 ...
- java认证授权(Spring Security)
目录 1.Spring Security介绍 2.认证授权入门 2.2.1 创建认证服务工程 1.部署认证服务工程 2.配置Spring Security所需要的依赖 3.初始工程自带了一个Contr ...
最新文章
- 简单的复数运算(类和对象)_JAVA
- flink source 同步_如何生成 Flink 作业的交互式火焰图?
- 电气专业学python吗_985大学毕业起薪最高的五个专业,计算机、金融、电气上榜!...
- flash player 11 相关资源
- python真的是吹过了-别再无脑吹了,python和matleb有什么不同你知道吗?
- 浅析Linux设备树dts相关知识
- 串口通信接口标准(三)——RS232
- 一个放在口袋里的项目,将社交裂变做到了极致
- android iphone滑动解锁,苹果iOS10锁屏详解:“滑动来解锁”已成为过去
- 工业通讯 | Profinet协议基础知识(一)
- java 大二学期总结报告_大二学生自我鉴定范文3篇
- ant.vue富文本编辑器_基于Vue.js 2.0和shimo Docs样式的富文本编辑器
- HTML——表白树动画
- 二手贴片机多少钱一台,二手贴片机转让
- 生成验证码_JSP源代码
- 编程之美——1.2 中国象棋将帅问题(转)
- metawrap quant_bins 的bin_abundance_table.tab结果理解
- 织梦dedecms网站如何转移搬家
- 文献笔记--相关:无线通信、安全加密隐私
- Windows 下安装MIMIC-IV
热门文章
- 最后一周报名微生物组-宏基因组分析(线上/线下同步开课,2020最后一期)
- 袁国勇院士团队纳米孔测序揭示人和禽流感病毒新型检测和监测靶点
- Nature综述:如何获得理想的微生物组
- R语言ggplot2地理信息可视化(上)
- R语言ggplot2地理信息可视化(下)
- 第七届“数学、计算机与生命科学交叉研究” 青年学者论坛
- R语言ggplot2可视化:ggplot2可视化使用guide_axis(check.overlap=TRUE)选项删除重叠的轴文本、跳过部分中间轴标签
- python使用sklearn的ConfusionMatrixDisplay来可视化混淆矩阵
- 机器学习特征筛选:方差选择法VarianceThreshold
- linux文件查找命令find、which、locate、whereis 和type