Spring Security过滤器链分析-初始化流程(8)

守听  金牌会员 | 2022-9-16 17:13:17 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 800|帖子 800|积分 2400

过滤器链分析

  提起Spring Security的实现原理,很多读者都会想到过滤器链。因为Spring Security中的所有功能都是通过过滤器来实现的,这些过滤器组成一个完整的过滤器链。那么,这些过滤器 链是如何初始化的?我们前面反复提到的AuthenticationManager又是如何初始化的?通过前面章节的学习,相信读者己经有了一些认识,本章我们将从头开始,分析Spring Security的初始化流程,同时再通过六个案例来让读者深入理解并且学会如何制作过滤器链。由于初始化流程相对复杂,因此我们没有选择在一开始就讲解Spring Security初始化流程,而是放到本节。当读者对于Spring Security有一个基本的认知之后再来讲解,此时相对来说就会比较容易理解。
本章涉及的主要知识点有:

  • 初始化流程分析。
  • ObjectPostProcessor 的使用。
  • 多种用户定义方式。
  • 定义多个过滤器链。
  • 静态资源过滤。
  • 使用JSON格式登录。
  • 添加登录验证码。
1. 初始化流程分析

  Spring Security初始化流程整体上来说理解起来并不难,但是这里涉及许多零碎的知识点, 把这些零碎的知识点搞懂了,再来梳理初始化流程就会容易很多。因此,这里先介绍一下SpringSecurity中一些常见的关键组件,在理解这些组件的基础上,再来分析初始化流程,就能加深对其的理解。
  1.1 ObjectPostProcessor  

  ObjectPostProcessor是Spring Security中使用频率最高的组件之一,它是一个对象后置处理器,也就是当一个对象创建成功后,如果还有一些额外的事情需要补充,那么可以通过 ObjectPostProcessor来进行处理。这个接口中默认只有一个方法postProcess,该方法用来完成对对象的二次处理,代码如下:
  1. public interface ObjectPostProcessor<T> {
  2.         <O extends T> O postProcess(O object);
  3. }
复制代码
  ObjectPostProcessor默认有两个继承类,如图4-1所示。
  
图 4-1

  • AutowireBeanFactoryObjectPostProcessor:由于 Spring Security 中大量采用了 Java 配置, 许多过滤器都是直接new出来的,这些直接new出来的对象并不会自动注入到Spring 容器中。Spring Security这样做的本意是为了简化配置,但是却带来了另外一个问题就是, 大量new出来的对象需要我们手动注册到Spring客器中去。AutowireBeanFactoryObjectPostProcessor对象所承担的就是这件事,一个对象new出来之后,只要调用 AutowireBeanFactoryObjectPostProcessor.postProcess 方法,就可以成功注入到 Spring 容器中,它的实现原理就是通过调用Spring容器中的AutowireCapableBeanFactory对象将一个new出来的对象注入到Spring容器中去。
  • CompositeObjectPostProcessor:这是ObjectPostProcessor 的另一个实现,一个对象可以有一个后置处理器,开发者也可以自定义多个对象后置处理器。 CompositeObjectPostProcessor是一个组合的对象后置处理器,它里边维护了一个List集合,集合中存放了某一个对象的所有后置处理器,当需要执行对象的后置处理器时,会遍历集合中的所有ObjectPostProcessor实例,分别调用实例的postProcess方法进行对象后置处理。在Spring Security框架中,最终使用的对象后置处理器其实就是 CompositeObjectPostProcessor ,它里边的集合默认只有一个对象,就是 AutowireBeanFactoryObjectPostProcessor。
  在Spring Security中,开发者可以灵活地配置项目中需要哪些Spring Security过滤器,一 旦选定过滤器之后,每一个过滤器都会有一个对应的配置器,叫作xxxConfigurer (例如CorsConfigurer. CsrfConfigurer等),过滤器都是在 xxxConfigurer 中 new 出来的,然后在 postProcess方法中处理一遍,就将这些过滤器注入到Spring容器中了。这是对象后置处理器ObjectPostProcessor的主要作用。
  1.2 SecurityFilterChain

  从名称上可以看出,SecurityFilterChain就是Spring Security中的过滤器链对象。下面来看一下 SecurityFilterChain的源码:
  1. public interface SecurityFilterChain {
  2.         boolean matches(HttpServletRequest request);
  3.         List<Filter> getFilters();
  4. }
复制代码
可以看到,SecurityFilterChain中有两个方法:

  • matches:该方法用来判断request请求是否应该被当前过滤器链所处理心
  • getFilters:该方法返回一个List集合,集合中存放的就是Spring Security中的过滤器。换言之,如果matches方法返回true,那么request请求就会在getFilters方法所返回的Filter 集合中被处理。
SecurityFilterChain只有一个默认的实现类就是DefaultSecurityFilterChain,其中定义了两 个属性,并具体实现了 SecurityFilterChain中的两个方法:
查看代码
  1.  public final class DefaultSecurityFilterChain implements SecurityFilterChain {
  2.         private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
  3.         private final RequestMatcher requestMatcher;
  4.         private final List<Filter> filters;
  5.         public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
  6.                 this(requestMatcher, Arrays.asList(filters));
  7.         }
  8.         public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
  9.                 logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
  10.                 this.requestMatcher = requestMatcher;
  11.                 this.filters = new ArrayList<>(filters);
  12.         }
  13.         public RequestMatcher getRequestMatcher() {
  14.                 return requestMatcher;
  15.         }
  16.         public List<Filter> getFilters() {
  17.                 return filters;
  18.         }
  19.         public boolean matches(HttpServletRequest request) {
  20.                 return requestMatcher.matches(request);
  21.         }
  22.         @Override
  23.         public String toString() {
  24.                 return "[ " + requestMatcher + ", " + filters + "]";
  25.         }
  26. }
复制代码
  可以看到,在DefaultSecurityFilterChain的构造方法中,需要传入两个对象,一个是请求 匹配器requestMatcher,另一个则是过滤器集合或者过滤器数组filters。这个实现类比较简单, 这里就不再赘述了。
  需要注意的是,在一个Spring Security项目中,SecurityFilterChain的实例可能会有多个,在后面的小节中会详细分析,并演示多个SecurityFilterChain实例的情况。
  1.3 SecurityBuilder

  Spring Security中所有需要构建的对象都可以通过SecurityBuilder来实现,默认的过滤器 链、代理过滤器AuthenticationManager 等,都可以通过 SecurityBuilder来构建。SecurityBuilder的实现类如图4-2所示。
  
图 4-2
  SecurityBuilder:
  我们先来看SecurityBuilder的源码:
  1. public interface SecurityBuilder<O> {
  2.         O build() throws Exception;
  3. }
复制代码
  由上述代码可以看到,SecurityBuilder中只有一个build方法,就是对象构建方法。build 方法的返回值,就是具体构建的对象泛型O,也就是说不同的SecurityBuilder将来会构建出不同的对象。
  HttpSecurityBuiIder:
  HttpSecurityBuilder是用来构建 HttpSecurity对象的,HttpSecurityBuilder 的定义如下:
[code]public interface HttpSecurityBuilder extends                SecurityBuilder {         C getConfigurer(                        Class clazz);             C removeConfigurer(                        Class clazz);             void setSharedObject(Class sharedType, C object);             C getSharedObject(Class sharedType);            H authenticationProvider(AuthenticationProvider authenticationProvider);            H userDetailsService(UserDetailsService userDetailsService) throws Exception;            H addFilterAfter(Filter filter, Class
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表