Spring Security中的Servlet过滤器体系代码分析

1. 前言

我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键。

2. Servlet Filter体系

这里我们以Servlet Web为讨论目标,Reactive Web暂不讨论。我们先来看下最基础的Servlet体系,在Servlet体系中客户端发起一个请求过程是经过0到N个Filter然后交给Servlet处理。

Filter不但可以修改HttpServletRequestHttpServletResponse,可以让我们在请求响应的前后做一些事情,甚至可以终止过滤器链FilterChain的传递。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
   // 请求被servlet 处理前
   if(condition){
    // 根据条件来进入下一个过滤器
     chain.doFilter(request, response);
   }
   // 请求被执行完毕后处理一些事情
 }

由于Filter仅影响下游Filters和Servlet,因此每个Filter调用的顺序非常重要。Spring Security正是根据这个个特性来实现一系列的安全功能。接下来我们来看看它们是如何结合的。

3. GenericFilterBean

在该系列的文章开篇我对Spring Security和Shiro进行了简单的对比。Spring Security利用了Spring IOC和AOP的特性而无法脱离Spring独立存在,而Apache Shiro可以独立存在。所以今天我们要一探究竟,看看他们是如何结合的。

Spring结合Servlet Filter自然是要为Servlet Filter注入Spring Bean的特性,所以就搞出了一个抽象Filter Bean,这个抽象过滤器GenericFilterBean并不是在Spring Security下,而是Spring Web体系中,类图如下:

从类图上看Filter接口已经被注入了多个Spring Bean的特性,纳入了Spring Bean生命周期,使得Spring IoC容器能够充分的管理Filter

4. DelegatingFilterProxy

我们希望Servlet能够按照它自己的标准来注册到过滤器链中工作,但是同时也希望它能够被Spring IoC管理,所以Spring提供了一个GenericFilterBean的实现DelegatingFilterProxy。我们可以将原生的Servlet Filter或者Spring Bean Filter委托给DelegatingFilterProxy,然后在结合到Servlet FilterChain中。

5. SecurityFilterChain

针对不同符合Ant Pattern的请求可能会走不同的过滤器链,比如登录会去验证,然后返回登录结果;管理后台的接口走后台的安全逻辑,应用客户端的接口走客户端的安全逻辑。Spring Security提供了一个SecurityFilterChain接口来满足被匹配HttpServletRequest走特定的过滤器链的需求。

public interface SecurityFilterChain {
  // 判断请求 是否符合该过滤器链的要求
  boolean matches(HttpServletRequest request);
  // 对应的过滤器链
  List<Filter> getFilters();
}

6. FilterChainProxy

不同的SecurityFilterChain应该是互斥而且平等的,它们之间不应该是上下游关系。

如上图请求被匹配到不同的SecurityFilterChain然后在执行剩余的过滤器链。它们经过SecurityFilterChain的总流程是相似的,而且有些时候特定的一些SecurityFilterChain也需要被集中管理来实现特定一揽子的请求的过滤逻辑。所以就有了另外一个GenericFilterBean实现来做这个事情,它就是FilterChainProxy。它的作用就是拦截符合条件的请求,然后根据请求筛选出符合要求的SecurityFilterChain,然后链式的执行这些Filter,最后继续执行剩下的FilterChain

扩展阅读:Spring Security 过滤器链

7. 总结

结合上面,最终上述这些概念的关系彻底搞清楚了,搞清楚过滤器的运作模式对于学习和使用Spring Security至关重要。

到此这篇关于Spring Security中的Servlet过滤器体系的文章就介绍到这了,更多相关Spring Security Servlet过滤器体系内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java servlet过滤器使用示例

    Servlet过滤器简介      Servlet过滤器实际上就是一个标准的java类,这个类通过实现Filter接口获得过滤器的功能.它在jsp容器启动的时候通过web.xml配置文件被系统加载.Servlet过滤器在接收到用户请求的时候被调用,当服务器接收到用户的请求的时候,依次调用配置好的过滤器,完成后将执行请求所要求的servlet,而servlet执行后的响应,则先通过配置好的过滤器后再发送给用户. 过滤器的用途:1.用户认证和授权管理.2.统计web应用的访问量和访问命中率,生成访问

  • Spring Security如何在Servlet中执行

    Spring Security 是一个强大的认证和授权框架,它的使用方式也非常简单,但是要想真正理解它就需要花一时间来学习了,最近在学习 Spring Security 时有一些新的理解,特意记录下来防止知识忘记的太快,毕竟好记性不如烂笔关,也给即将准备学习 Spring Security 的同志做一个参考. 由于我在学习和使用是基于 Servlet Applications 的,所以文中的大部分都与 Servlet 相关,当然 Spring Security 还支持 Reactive Appl

  • servlet+jsp实现过滤器 防止用户未登录访问

    我们可能经常会用到这一功能,比如有时,我们不希望用户没有进行登录访问后台的操作页面,而且这样的非法访问会让系统极为的不安全,所以我们常常需要进行登录才授权访问其它页面,否则只会出现登录页面,当然我的思路: 一种是在jsp页面进行session的判断,如果不存在该用户的session,就跳转到登录页面,否则执行jsp页面代码,但是你会发现这样做逻辑也简单,但是非常麻烦,如果有很多个jsp,那么就要写多个判断. 另一种则是利用过滤器,访问页面时都进行过滤验证,如果存在该用户session,则访问该页

  • 深入解析Java的Servlet过滤器的原理及其应用

    1.Servlet过滤器 1.1 什么是过滤器 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息.在这之后,过滤器可以作如下的选择: ①以常规的方式调用资源(即,调用servlet或JSP页面). ②利用修改过的请求信息调用资源. ③调用资源,但在发送响应到客户机前对其进行修改. ④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出.   1.2 Servl

  • 基于java servlet过滤器和监听器(详解)

    1 过滤器 1.过滤器是什么? servlet规范当中定义的一种特殊的组件,用于拦截容器的调用. 注:容器收到请求之后,如果有过滤器,会先调用过滤器,然后在调用servlet. 2.如何写一个过滤器? 1.写一个java类,实现Filter接口; 2.在接口方法中实现拦截方法; 3.配置过滤器(web.xml); 3.配置初始化参数 1.配置初始化参数.(init-param) 2.通过filterconfig提供的getinitparamenter方法读取初始化的值. 4.优先级: 当有多个过

  • Spring Security中的Servlet过滤器体系代码分析

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"."授权"."防止利用漏洞"的关键. 2. Servlet Filter体系 这里我们以Servlet Web为讨论目标,Reactive Web暂不讨论.我们先来看下最基础的Servlet体系,在Servlet体系中客户端发起

  • Spring Security 图片验证码功能的实例代码

    验证码逻辑 以前在项目中也做过验证码,生成验证码的代码网上有很多,也有一些第三方的jar包也可以生成漂亮的验证码.验证码逻辑很简单,就是在登录页放一个image标签,src指向一个controller,这个Controller返回把生成的图片以输出流返回给页面,生成图片的同时把图片上的文本放在session,登录的时候带过来输入的验证码,从session中取出,两者对比.这位老师讲的用Spring Security集成验证码,大体思路和我说的一样,但更加规范和通用些. spring securi

  • 详解Spring Security中的HttpBasic登录验证模式

    一.HttpBasic模式的应用场景 HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式,也可以说是最简陋的一种方式.它的目的并不是保障登录验证的绝对安全,而是提供一种"防君子不防小人"的登录验证. 就好像是我小时候写日记,都买一个带小锁头的日记本,实际上这个小锁头有什么用呢?如果真正想看的人用一根钉子都能撬开.它的作用就是:某天你的父母想偷看你的日记,拿出来一看还带把锁,那就算了吧,怪麻烦的. 举一个我使用HttpBasic模式的进行登录验证的

  • spring security中的csrf防御原理(跨域请求伪造)

    什么是csrf? csrf又称跨域请求伪造,攻击方通过伪造用户请求访问受信任站点.CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报).Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为"沉睡的巨人". 举个例子,用户通过表单发送请求到银行网站,银行

  • Spring Security 中如何让上级拥有下级的所有权限(案例分析)

    答案是能! 松哥之前写过类似的文章,但是主要是讲了用法,今天我们来看看原理! 本文基于当前 Spring Security 5.3.4 来分析,为什么要强调最新版呢?因为在在 5.0.11 版中,角色继承配置和现在不一样.旧版的方案我们现在不讨论了,直接来看当前最新版是怎么处理的. 1.角色继承案例 我们先来一个简单的权限案例. 创建一个 Spring Boot 项目,添加 Spring Security 依赖,并创建两个测试用户,如下: @Override protected void con

  • 解决Spring Security中AuthenticationEntryPoint不生效相关问题

    目录 在这里我的代码如下 用不存在的用户名密码登录后会出现以下返回数据 以下是配置信息 以下是实现的验证码登录过滤器 以下是对应的源码 我们首先看一下当前Security的拦截器链 为了保证拦截器链能顺利到达ExceptionTranslationFilter 之前由于项目需要比较详细地学习了Spring Security的相关知识,并打算实现一个较为通用的权限管理模块.由于项目是前后端分离的,所以当认证或授权失败后不应该使用formLogin()的重定向,而是返回一个json形式的对象来提示没

  • 详解Spring Security中权限注解的使用

    目录 1. 具体用法 2. SpEL 3. @PreAuthorize 最近有个小伙伴在微信群里问 Spring Security 权限注解的问题: 很多时候事情就是这么巧,松哥最近在做的 tienchin 也是基于注解来处理权限问题的,所以既然大家有这个问题,咱们就一块来聊聊这个话题. 当然一些基础的知识我就不讲了,对于 Spring Security 基本用法尚不熟悉的小伙伴,可在公众号后台回复 ss,有原创的系列教程. 1. 具体用法 先来看看 Spring Security 权限注解的具

  • 图解Spring Security 中用户是如何实现登录的

    1. 前言 欢迎阅读Spring Security 实战干货系列文章,在集成Spring Security安全框架的时候我们最先处理的可能就是根据我们项目的实际需要来定制注册登录了,尤其是Http登录认证.根据以前的相关文章介绍,Http登录认证由过滤器UsernamePasswordAuthenticationFilter 进行处理.我们只有把这个过滤器搞清楚才能做一些定制化.今天我们就简单分析它的源码和工作流程. 2. UsernamePasswordAuthenticationFilter

  • 详解Spring Security中获取当前登录用户的详细信息的几种方法

    目录 在Bean中获取用户信息 在Controller中获取用户信息 通过 Interface 获取用户信息 在JSP页面中获取用户信息 在Bean中获取用户信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (!(authentication instanceof AnonymousAuthenticationToken)) { String currentU

随机推荐