spring security filter

2023-05-16

一、spring security过滤器默认配置

WebSecurityConfigurerAdapter.init()
WebSecurityConfigurerAdapter.getHttp()
new HttpSecurity()
new FilterComparator()
按优先级顺序放入,前面的优先级比后面的高,关键的filter
Step order = new Step(INITIAL_ORDER, ORDER_STEP);
put(ChannelProcessingFilter.class, order.next());
put(ConcurrentSessionFilter.class, order.next());
put(WebAsyncManagerIntegrationFilter.class, order.next());
put(SecurityContextPersistenceFilter.class, order.next());
put(HeaderWriterFilter.class, order.next());
put(CorsFilter.class, order.next());
put(CsrfFilter.class, order.next());
put(LogoutFilter.class, order.next());
filterToOrder.put(   "org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter", order.next());
put(X509AuthenticationFilter.class, order.next());
put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter",
        order.next());
filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
        order.next());
put(UsernamePasswordAuthenticationFilter.class, order.next());
put(ConcurrentSessionFilter.class, order.next());
filterToOrder.put(
        "org.springframework.security.openid.OpenIDAuthenticationFilter", order.next());
put(DefaultLoginPageGeneratingFilter.class, order.next());
put(DefaultLogoutPageGeneratingFilter.class, order.next());
put(ConcurrentSessionFilter.class, order.next());
put(DigestAuthenticationFilter.class, order.next());
filterToOrder.put(
        "org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter", order.next());
put(BasicAuthenticationFilter.class, order.next());
put(RequestCacheAwareFilter.class, order.next());
put(SecurityContextHolderAwareRequestFilter.class, order.next());
put(JaasApiIntegrationFilter.class, order.next());
put(RememberMeAuthenticationFilter.class, order.next());
put(AnonymousAuthenticationFilter.class, order.next());
filterToOrder.put(
    "org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter",
        order.next());
put(SessionManagementFilter.class, order.next());
put(ExceptionTranslationFilter.class, order.next());
put(FilterSecurityInterceptor.class, order.next());
put(SwitchUserFilter.class, order.next());

二、springsecurity过滤器链springSecurityFilterChain通过代理创建(懒加载)

1、oauth2认证中心

查看容器中的关于springsecurity需要的filter(springSecurityFilterChain),需要跟踪tomcat支持包下的ApplicationFilterFactory类,查看返回的过滤器链对象filterChain,ApplicationFilterFactory.createFilterChain(ServletRequest request,Wrapper wrapper, Servlet servlet),也可以查看DelegatingFilterProxy.initDelegate(WebApplicationContext wac),这个方法是在执行DelegatingFilterProxy的doFilter方法时才会执行,达到懒加载delegate的目的。

适配后的过滤器链

token相关(/oauth/token,/oauth/token_key,/oauth/check_token)的springSecurityFilterChain过滤器链(按优先级顺序)
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
ClientCredentialsTokenEndpointFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor


anyRequest相关springSecurityFilterChain的过滤器链
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
UsernamePasswordAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor

2、oauth2的SSO客户端(@EnableOAuth2Sso)过滤器如下:

客户端注解@EnableOAuth2Client引入的过滤器
OAuth2ClientContextFilter

客户端的springSecurityFilterChain过滤器链

WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
OAuth2ClientAuthenticationProcessingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor

三、springsecurity过滤器链所处容器中过滤器链的位置如下图所示

在这里插入图片描述

四、请求与过滤器链

1、springSecurityFilterChain

初始化过滤器:启动tomcat容器时,ServletContextInitializerBeans.addAdaptableBeans会从beanFactory将实现javax.servlet.Filter接口相关的bean(含springSecurityFilterChain类型为DelegatingFilterProxyRegistrationBean)加载到initializers
再执行ServletContextInitializerBeans.onStartup(ServletContext servletContext)将执行springSecurityFilterChain.getFilter()获取到DelegatingFilterProxy的实例并添加到容器ServletContext(即ApplicationContext,真正存入StandardContext,filter以FilterDef类型存储)中。

2、处理请求

1)调用tomcat的类StandardWrapperValve的invoke方法,获取整体的过滤器链ApplicationFilterChain并执行。

获取整体的过滤器链ApplicationFilterFactory.createFilterChain从StandardContext中获取适合的过滤器配置(ApplicationFilterConfig)添加到过滤器链中。

public final void invoke(Request request, Response response)
        throws IOException, ServletException {
        ....
        // Create the filter chain for this request
        ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

        // Call the filter chain for this request
        // NOTE: This also calls the servlet's service() method
        Container container = this.container;
        try {
            ....
            filterChain.doFilter(request.getRequest(),
                    response.getResponse());

            ....          
        } catch (Exception e) {
            .....
        } finally {
            // Release the filter chain (if any) for this request
            if (filterChain != null) {
                filterChain.release();
            }
            ....
    }

ApplicationFilterChain过滤器链执行方法doFilter,内部执行internalDoFilter方法

private void internalDoFilter(ServletRequest request,
                                  ServletResponse response)
        throws IOException, ServletException {
    // Call the next filter if there is one
    if (pos < n) {
        ApplicationFilterConfig filterConfig = filters[pos++];//获取过滤器链中下一个过滤器配置
        try {
            Filter filter = filterConfig.getFilter();//从配置中得到过滤器
            .....
            filter.doFilter(request, response, this);//过滤器执行时,需要将当前的过滤器链作为参数传入,以便在过滤器内部执行过滤器链的doFilter方法,调用下一个过滤器,实现过滤器的链式调用
           
        }
    }    
    ....
}

2)执行springsecurity的过滤器链springSecurityFilterChain

当执行到springSecurityFilterChain,再执行DelegatingFilterProxy.doFilter、initDelegate完成对FilterChainProxy(delegate真正的springSecurity过滤器链)的实例的创建,  再执行DelegatingFilterProxy.invokeDelegate方法,调用FilterChainProxy.doFilter执行doFilterInternal方法创建VirtualFilterChain(这个就是springsecurity真正的过滤器链,包含原始的过滤器链ApplicationFilterChain和springsecurity的过滤器列表)并执行它的doFilter来开始执行springsecurity的过滤器链,内部先执行springsecurity的过滤器链,最后再回到原始的过滤器链originalChain(ApplicationFilterChain),继续执行后续的过滤器。

    public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException {
        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 chain
            this.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);
        }
    }

3)过滤器链执行流程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring security filter 的相关文章

随机推荐

  • 线程同步之信号量(sem_init,sem_post,sem_wait)

    信号量和互斥锁 mutex 的区别 xff1a 互斥锁只允许一个线程进入临界区 xff0c 而信号量允许多个线程同时进入临界区 不多做解释 xff0c 要使用信号量同步 xff0c 需要包含头文件semaphore h 主要用到的函数 xf
  • 老程序员给的10条建议,句句经典

    1 想清楚 xff0c 再动手写代码 刚入行的新手 xff0c 为了展示自己的能力 xff0c 拿到需求迫不及待地就开始上手写代码 xff0c 大忌 xff01 2 不交流 xff0c 就会头破血流 不爱说话和沟通 xff0c 需求都理解错
  • Clickhouse快速上手 原理篇

    1 背景 公司目前使用Greenplum作为报表实时聚合查询的OLAP数据库 xff0c 当时主要是其使用门槛相对较低 xff0c 同时支持事务 xff0c 能在用户访问时候事务更新数据 xff0c 使用云厂商的产品 xff0c 技术支持也
  • Clickhouse快速上手 使用篇

    接着clickhouse原理篇 xff0c 下面来介绍他的具体使用场景 xff0c 包括数据导入 xff0c 更新等 文章目录 1 数据导入调研计划实施1 cos文件系统集成2 编码获取 2 数据更新和使用 1 数据导入 根据官方介绍 Cl
  • linux基本服务之sshd

    这段时间在学习linux常用服务 xff0c 这里将学习内容以及自己的实验心得记录下来 在自己忘记的时候也好复习 实验环境 xff1a centos 6 7 64bit 1 简介 SSHD服务 介绍 xff1a SSH协议 xff1a 安全
  • Git+VSCode基本使用

    前言 由于工作需要 xff0c 最近简单学习了git xff0c 巧合发现了VSCODE编辑器正好集成了git命令 xff0c 使得本地代码管理变得更加容易 因为最后是在linux下交叉编译 xff0c 但是我更习惯windows下写代码
  • 掌握音频开发基础知识

    文章目录 基本概念几种CODEC介绍实时调度相关缓冲区两种类型编写要点遇到的问题 解码能力的自适应混音模块回声消除的延时控制能量统计双声道支持ALSA设备 代码相关 基本概念 采样率 Hz 每秒去取样本的个数 xff0c eg 48000H
  • CSDN日报20170616 ——《从裁缝到码农》

    程序人生 从裁缝到码农 作者 xff1a 修电脑的裁缝酱 我伸出颤抖的手去抓 xff0c 发现曾经遥不可及的梦想 xff0c 经过坚持和努力之后 xff0c 真的可以抓住 我把它抓在手心 xff0c 紧紧地 点击阅读全文 机器学习 一文了解
  • Java中char类型详解

    1 基本定义 char类型的值可以表示为十六进制值 xff0c 其范围从 u0000 到 uffff xff0c 由两个字节构成 char类型原本用于表示单个字符 xff0c 但是现在情况有所变化 xff0c 有些Unicode字符需要一个
  • Git命令行简单使用小结

    最近复习了一下git 总结了一下命令行的基本使用 0 基本理论 a 基本概念 Working Directory 就是平时存放项目代码的地方 Stage Index 用于临时存放改动 事实上他只是一个文件 保存即将提交的文件列表信息 Rep
  • 无外接环境下,单笔记本直连浪潮服务器BMC灌装系统

    1 环境因素 xff1a 单服务器无网络无显示器等外接 xff0c 需要对浪潮防火墙灌装系统 xff1b 2 所需材料 xff1a 1 浪潮服务器 2 可接网线笔记本电脑 xff08 Windows平台 xff09 3 网线一根 3 连接拓
  • python抽样方法详解及实现

    抽样方法概览 随机抽样 总体个数较少 每个抽样单元被抽中的概率相同 xff0c 并且可以重现 随机抽样常常用于总体个数较少时 xff0c 它的主要特征是从总体中逐个抽取 1 抽签法 2 随机数法 xff1a 随机数表 随机数骰子或计算机产生
  • ROS 1.0 学习笔记(6)CMakeLists.txt 使用说明

    ROS1中每个PKG的配置都是在CMakeList txt中 xff0c 本文从官方 WiKi 资料中翻译而来 1 概览 文件CMakeLists txt是CMake编译系统的配置文件 xff0c 用于配置需要编译软件包 任何兼容CMake
  • LQR控制算法推导以及简单分析

    首先 xff0c 这篇文章是看了几个大神的博客后 xff0c 自己抄录以及整理的内容 xff0c 其中有些自己的想法 xff0c 但是原理部分基本都是学习大神们的 xff0c 在此先说明一下 1 全状态反馈控制系统 在介绍LQR之前 xff
  • C++ Primer(第五版)|练习题答案与解析(第三章:字符串、向量和数组)

    C 43 43 Primer 第五版 练习题答案与解析 第三章 字符串 向量和数组 本博客主要记录C 43 43 Primer 第五版 中的练习题答案与解析 参考 C 43 43 Primer C 43 43 Primer 练习题3 2 编
  • ROS学习(五)导航、路径规划、SLAM

    主要涉及到3个基本包 用于让机器人在制定框架内移动到目标位置的move base包 用于从激光扫描仪 深度摄像机来绘制地图的gmapping包 用于在现有的地图中定位的amcl包 先阅读 http wiki ros org navigati
  • 微服务架构模型和进程间通信

    微服务架构 微服务的扩展模型X轴扩展在多个相同实例之间实现请求的负载均衡Y轴扩展根据功能将应用程序拆分为服务Z轴扩展根据请求的属性路由请求微服务架构与SOA的异同微服务架构的好处微服务架构的弊端 微服务进程间通信基于同步远程过程调用模式的通
  • 关于搭建guacamole-server.1.4.0简单步骤,及问题记录

    问题1 xff1a 在guacamole server 1 4 0目录下 xff0c 执行 configure 发现记录中出现以下警告 xff0c 并且VNC没有成功加载 xff08 libvncserver devel已经导入yum的情况
  • 【获奖公布】征文 | 你会为 AI 转型么?

    AI xff08 Artificial Intelligence xff09 xff0c 即人工智能 人工智能领域的研究包括机器人 语音识别 图像识别 自然语言处理和专家系统等 人工智能从诞生以来 xff0c 理论和技术日益成熟 xff0c
  • spring security filter

    一 spring security过滤器默认配置 WebSecurityConfigurerAdapter init WebSecurityConfigurerAdapter getHttp new HttpSecurity new Fil