上一节中,主要讲了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. 视觉SLAM关键方法总结

    点"计算机视觉life"关注,置顶更快接收消息! 最近在做基于激光信息的机器人行人跟踪发现如果单独利用激光信息很难完成机器人对行人的识别.跟踪等功能,因此考虑与视觉融合的方法,这样 ...

  2. temp数据预处理--以24h为周期的序列

    1.按照周期来截取数据 从数据库加载下来的是以5min取一次mean()的列,因此24h应取了24*60/5=288次数据 首先把这8352个数据(最后一个以倒数第二个填充)改成288*30的形式 t ...

  3. 201871010111-刘佳华《面向对象程序设计(java)》第十七周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第十七周学习总结 实验十七  线程同步控制 实验时间 2019-12-20 第一部分:理论知识总结 16.Java 的线程调 ...

  4. mysql查询表中最后一条记录

    查询全部的记录:            select * from test_limit ; 查第一条记录:             select * from test_limit limit 1; ...

  5. nginx中ngx_http_access_module模块

    实现基于IP的访问控制功能指令:4.1 allow允许访问指定的⽹网络或地址Syntax: allow address | CIDR | unix:| all;Default: —Context: h ...

  6. 四、vue基础--自定义组件

    1.语法:Vue.component("组件名字",{data,template}),代码如下: a. data: 必须是一个函数,有一个返回值.和vue里面的使用方法一样 b. ...

  7. jaxb生成pojo类返回类型为布尔值的问题

    返回值为Boolean的话回在对象转json的时候丢失掉这个属性,因为json认的是小写. 这个算jaxb的一个bug:https://java.net/jira/browse/JAXB-510 解决 ...

  8. System.Web.HttpRequestValidationException: 从客户端(name="<a href=''>我是晓菜鸟</a>")中检测到有潜在危险的 Request.Form 值

    这是一个比较常见的问题了,如果Web表单中有输入类似于 Html 标签之类的文本,在通过 Request.QueryString 或者 Request.Form 传递这些值的时候,就会触发这样的异常, ...

  9. [AH2017/HNOI2017]抛硬币(扩展lucas)

    推式子+exlucas. 题意: 小 A 和小 B 是一对好朋友,两个人同时抛 b 次硬币,如果小 A 的正面朝上的次数大于小 B 正面朝上的次数,则小 A 获胜. 小 A 决定在小 B 没注意的时候 ...

  10. FileInputStream读取的两种方法:逐字节读;以字节数组读取

    1:read() : 从输入流中读取数据的下一个字节,返回0到255范围内的int字节值.如果因为已经到达流末尾而没有可用的字节,则返回-1.在输入数据可用.检测到流末尾或者抛出异常前,此方法一直阻塞 ...