上一节中,主要讲了Spring Security认证和授权的核心组件及核心方法。但是,什么时候调用这些方法呢?答案就是Filter和AOP。Spring Security在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问。
对于基于HttpRequest的方式对端点进行保护,我们使用一个Filter Chain来保护;对于基于方法调用进行保护,我们使用AOP来保护。本篇重点讲Spring Security中过滤器链的种类及过滤器中如何实现的认证和授权。

Spring Security会默认为我们添加15个过滤器,我们可以从WebSecurity(WebSecurity是Spring Security加载的一个重要对象,将在下节具体讲述)的performBuild()方法中看到过滤器链SecurityFilterChain的构建过程,并交由FilterChainProxy对象代理。我们从SecurityFilterChain的默认实现类DefaultSecurityFilterChain中的log看出,Spring Security由以下过滤器组成了过滤器链:

Creating filter chain: any request, [
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7f353a0f,
org.springframework.security.web.context.SecurityContextPersistenceFilter@4735d6e5,
org.springframework.security.web.header.HeaderWriterFilter@314a31b0,
org.springframework.security.web.csrf.CsrfFilter@4ef2ab73,
org.springframework.security.web.authentication.logout.LogoutFilter@57efc6fd,
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@d88f893,
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@2cd388f5,
org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@7ea2412c,
org.springframework.security.web.authentication.www.BasicAuthenticationFilter@2091833,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4dad0eed,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@16132f21,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1c93b51e,
org.springframework.security.web.session.SessionManagementFilter@59edb4f5,
org.springframework.security.web.access.ExceptionTranslationFilter@104dc1a2,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1de0641b
]

下面就是各个过滤器的功能,其中SecurityContextPersistenceFilter,UsernamePasswordAuthenticationFilter及FilterSecurityInterceptor分别对应了上节SecurityContext,AuthenticationManager,AccessDecisionManager的处理。

[WebAsyncManagerIntegrationFilter] (异步方式)提供了对securityContext和WebAsyncManager的集成。方式是通过SecurityContextCallableProcessingInterceptor的beforeConcurrentHandling(NativeWebRequest, Callable)方法来将SecurityContext设置到Callable上。其实就是把SecurityContext设置到异步线程中,使其也能获取到用户上下文认证信息。

[SecurityContextPersistenceFilter] (同步方式)在请求之前从SecurityContextRepository(默认实现是HttpSessionSecurityContextRepository)获取信息并填充SecurityContextHolder(如果没有,则创建一个新的ThreadLocal的SecurityContext),并在请求完成并清空SecurityContextHolder并更新SecurityContextRepository。

在Spring Security中,虽然安全上下文信息被存储于Session中,但实际的Filter中不应直接操作Session(过滤器一般负责核心的处理流程,而具体的业务实现,通常交给其中聚合的其他实体类),而是用如HttpSessionSecurityContextRepository中loadContext(),saveContext()来存取session。

[HeaderWriterFilter] 用来给http响应添加一些Header,比如X-Frame-Options,X-XSS-Protection*,X-Content-Type-Options。

[CsrfFilter] 默认开启,用于防止csrf攻击的过滤器

[LogoutFilter] 处理注销的过滤器

[UsernamePasswordAuthenticationFilter] 表单提交了username和password,被封装成UsernamePasswordAuthenticationToken对象进行一系列的认证,便是主要通过这个过滤器完成的,即调用AuthenticationManager.authenticate()。在表单认证的方法中,这是最最关键的过滤器。具体过程是:

(1)调用AbstractAuthenticationProcessingFilter.doFilter()方法执行过滤器

(2)调用UsernamePasswordAuthenticationFilter.attemptAuthentication()方法

(3)调用AuthenticationManager.authenticate()方法(实际上委托给AuthenticationProvider的实现类来处理)

[DefaultLoginPageGeneratingFilter] & [DefaultLogoutPageGeneratingFilter] 如果没有配置/login及login page, 系统则会自动配置这两个Filter。

[BasicAuthenticationFilter] Processes a HTTP request's BASIC authorization headers, putting the result into the SecurityContextHolder.

[RequestCacheAwareFilter] 内部维护了一个RequestCache,用于缓存request请求

[SecurityContextHolderAwareRequestFilter] 此过滤器对ServletRequest进行了一次包装,使得request具有更加丰富的API(populates the ServletRequest with a request wrapper which implements servlet API security methods)

[AnonymousAuthenticationFilter] 匿名身份过滤器,spring security为了兼容未登录的访问,也走了一套认证流程,只不过是一个匿名的身份。它位于身份认证过滤器(e.g. UsernamePasswordAuthenticationFilter)之后,意味着只有在上述身份过滤器执行完毕后,SecurityContext依旧没有用户信息,AnonymousAuthenticationFilter该过滤器才会有意义。

[SessionManagementFilter] 和session相关的过滤器,内部维护了一个SessionAuthenticationStrategy来执行任何与session相关的活动,比如session-fixation protection mechanisms or checking for multiple concurrent logins。

[ExceptionTranslationFilter] 异常转换过滤器,这个过滤器本身不处理异常,而是将认证过程中出现的异常(AccessDeniedException and AuthenticationException)交给内部维护的一些类去处理。它
位于整个springSecurityFilterChain的后方,用来转换整个链路中出现的异常,将其转化,顾名思义,转化以意味本身并不处理。一般其只处理两大类异常:AccessDeniedException访问异常和AuthenticationException认证异常。

它将Java中的异常和HTTP的响应连接在了一起,这样在处理异常时,我们不用考虑密码错误该跳到什么页面,账号锁定该如何,只需要关注自己的业务逻辑,抛出相应的异常便可。如果该过滤器检测到AuthenticationException,则将会交给内部的AuthenticationEntryPoint去处理,如果检测到AccessDeniedException,需要先判断当前用户是不是匿名用户,如果是匿名访问,则和前面一样运行AuthenticationEntryPoint,否则会委托给AccessDeniedHandler去处理,而AccessDeniedHandler的默认实现,是AccessDeniedHandlerImpl。

[FilterSecurityInterceptor] 这个过滤器决定了访问特定路径应该具备的权限,这些受限的资源访需要什么权限或角色,这些判断和处理都是由该类进行的。

(1)调用FilterSecurityInterceptor.invoke()方法执行过滤器

(2)调用AbstractSecurityInterceptor.beforeInvocation()方法

(3)调用AccessDecisionManager.decide()方法决策判断是否有该权限

Spring Security(2):过滤器链(filter chain)的介绍的更多相关文章

  1. Spring Security 多过滤链的使用

    Spring Security 多过滤链的使用 一.背景 二.需求 1.给客户端使用的api 2.给网站使用的api 三.实现方案 方案一: 方案二 四.实现 1.app 端 Spring Secur ...

  2. Spring Security入门(1-12)Spring Security 的过滤器机制

    Servlet过滤器被用来拦截用户请求来进行请求之前或之后的处理,或者干脆重定向这个请求,这取决于servlet过滤器的功能. Servlet过滤器处理之后的目标servlet是 MVC 分发web ...

  3. Spring Security(09)——Filter

    目录 1.1     Filter顺序 1.2     添加Filter到FilterChain 1.3     DelegatingFilterProxy 1.4     FilterChainPr ...

  4. Spring Security 入门(1-6-2)Spring Security - 内置的filter顺序、自定义filter、http元素和对应的filterChain

    Spring Security 的底层是通过一系列的 Filter 来管理的,每个 Filter 都有其自身的功能,而且各个 Filter 在功能上还有关联关系,所以它们的顺序也是非常重要的. 1.S ...

  5. spring boot 自定义过滤器链

    spring boot 会按照order值的大小,从大到小的顺序来依次过滤. 贴下代码: package com.osp.ucenter; import org.springframework.boo ...

  6. spring security 图解过滤器的使用

    1. HttpSessionContextIntegrationFilter 位于过滤器顶端,第一个起作用的过滤器. 用途一,在执行其他过滤器之前,率先判断用户的session中是否已经存在一个Sec ...

  7. Spring Security 中的过滤器

    本文基于 spring-security-core-5.1.1 和 tomcat-embed-core-9.0.12. Spring Security 的本质是一个过滤器链(filter chain) ...

  8. Spring Security:Servlet 过滤器(三)

    3)Servlet 过滤器 Spring Security 过滤器链是一个非常复杂且灵活的引擎.Spring Security 的 Servlet 支持基于 Servlet 过滤器,因此通常首先了解过 ...

  9. Spring Security拦截器加载流程分析--练气中期

    写在前面 上回我们讲了spring security整合spring springmvc的流程,并且知道了spring security是通过过滤器链来进行认证授权操作的.今天我们来分析一下sprin ...

随机推荐

  1. Exams(二分

    题意:给你每天要考的科目,和每门科目需要复习多长时间,问最少需要几天才能完成所有的考试. 思路:二分答案,然后判断答案是否可行,这边需要进行贪心,即倒着往前推, 比如第i天,那么前面有i-1天是,可供 ...

  2. 2018江苏徐州icpc试题-A-生化危机【多源点-基础广搜】

  3. linux 确定端口使用情况

    lsof -i:3533 确定端口已经在使用

  4. 如何用pycharm 控制远程服务器来跑代码!!!!!!!!!!!!非常牛逼

    2019-09-04,10点58 想弄一个pycharm的插件,就是用deployment同步代码的时候,在pycharm里面运行代码,的时候本机不动,而是远程服务器运行,然后把结果返回!!!!!!挺 ...

  5. 25、自动装配-@Profile根据环境注册bean

    25.自动装配-@Profile根据环境注册bean 指定组件在哪个环境的情况下才能被注册到容器中 加了环境标识的,只有这个环境被激活才能注册到组件中 默认是default环境 写在类上,整个配置类的 ...

  6. 4、Spring Boot 2.x 自动配置原理

    1.4 Spring Boot 自动配置原理 简介 spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子: Spring的JdbcTemplate ...

  7. [Luogu] U18430 萌萌的大河

    https://www.luogu.org/problemnew/show/U18430 思路比较好想 树链剖分 对于1操作 只需将以该点为根的子树打标记,将所有数存入数组排序 每次进行1操作时,判断 ...

  8. seq2seq聊天模型(三)—— attention 模型

    注意力seq2seq模型 大部分的seq2seq模型,对所有的输入,一视同仁,同等处理. 但实际上,输出是由输入的各个重点部分产生的. 比如: (举例使用,实际比重不是这样) 对于输出"晚上 ...

  9. 一行代码加快pandas计算速度

    一行代码加快pandas计算速度 DASK https://blog.csdn.net/sinat_38682860/article/details/84844964 https://cloud.te ...

  10. 2015 ACM Arabella Collegiate Programming Contest

    题目链接:https://vjudge.net/contest/154238#overview. ABCDE都是水题. F题,一开始分类讨论,结果似乎写挫了,WA了一发.果断换并查集上,A了. G题, ...