Spring Security源码分析

Spring Security是一套访问控制的框架,主要的功能是验证和授权。

一、整体设计

从官方文档了解Spring Security的架构设计,Spring Security支持ServletWebFlux

SpringSecurity 本质是一个过滤器链,从启动开始可以获取到的过滤器链包括:

org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
org.springframework.security.web.context.SecurityContextPersistenceFilter 
org.springframework.security.web.header.HeaderWriterFilter 
org.springframework.security.web.csrf.CsrfFilter 
org.springframework.security.web.authentication.logout.LogoutFilter 
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter 
org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter 
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter 
org.springframework.security.web.session.SessionManagementFilter 
org.springframework.security.web.access.ExceptionTranslationFilter 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor

从官网中选取最具代表性的一张架构设计图,可以清晰的看到客户端发送的请求,需要经过一系列的过滤器后才能执行真正的Servlet方法,Spring Security就是过滤器链中的其中一环。根据官方介绍,Spring Security中主要有2个类和1个接口,分别是DetegatingFilterProxy、FilterChainProxy和SecurityFilterChain。
在这里插入图片描述
Spring Security的运行流程主要是由DetegatingFilterProxy进行分派,真正要执行的过滤器链由FilterChainProxy进行代理。在容器启动的时候,通过@Bean注解会在IOC容器里面创建SpringSecurityFilterChain,而SpringSecurityFilterChain其本质就是FilterChainProxy对象。在创建SpringSecurityFilterChain时,会通过FilterChainProxy的有参构造器注入默认的DefaultSecurityFilterChain和调用SecurityFilterChainBuilder的build方法生成的DefaultSecurityFilterChain。默认的DefaultSecurityFilterChain中没有任何过滤器,但是调用SecurityFilterChainBuilder的build方法生成的DefaultSecurityFilterChain里面就会注入Spring Security的一系列默认的过滤器。SecurityFilterChain是一个接口,接口里面定义了 matches方法和getFilters方法。FilterChainProxy执行过滤的时候会先调用SecurityFilterChain的matches方法,看是否满足匹配条件,如果不满足就继续下一个SecurityFilterChain。如果满足匹配条件,就会调用getFilters方法来获取到注册的过滤器,然后执行过滤器的doFilter方法进行过滤。

过滤成功和失败都提供了回调的接口,可以自定义实现,

二、运行流程

1、DetegatingFilterProxy创建

Servlet容器初始化,会创建了DelegatingFilterProxyWebApplicationInitializer接口的onStartup方法将会在Servlet容器启动时被调用,AbstractSecurityWebApplicationInitializer实现了该接口,因此AbstractSecurityWebApplicationInitializer的onStartup方法将被调用。在onStartup方法中,有一个insertSpringSecurityFilterChain方法。 可以看到在insertSpringSecurityFilterChain方法中创建了DelegatingFilterProxy对象,并将DelegatingFilterProxy对象添加到了Servlet的过滤器链中。进入DelegatingFilterProxy的构造器可以看到将DelegatingFilterProxy的成员变量targetBeanName赋值成了DEFAULT_FILTER_NAME,即springSecurityFilterChain。

spring web 应用启动时会调用onStartup
AbstractSecurityWebApplicationInitializer实现了该方法,用于创建DelegatingFilterProxy
在这里插入图片描述
在这里插入图片描述

2、DelegatingFilterProxy分派任务

DelegatingFilterProxy被创建后加入到了Servlet容器的过滤器链中,并且作为第一个过滤器,因此DelegatingFilterProxy的doFilter方法将在用户发起请求后被调用。 在doFilter方法中会执行initDelegate 和invokeDelegate方法
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
通过上述代码可以看出 DelegatingFilterProxy将真正的过滤操作分派给了delegateToUse这个局部变量。继续查看源码,看delegateToUse是什么。 可以看到delegateToUse是从WebApplicationContext里面根据BeanName获取到的,而targetBeanName在之前已经设置为springSecurityFilterChain。

因此,DelegatingFilterProxy其实就是将真正的过滤操作转派给了一个BeanName为springSecurityFilterChain的对象。

接下来我们的问题就变成了BeanName为springSecurityFilterChain的对象是什么。
在这里插入图片描述
在WebSecurityConfiguration这个配置类中,创建了springSecurityFilterChain。那这个对象到底是什么呢,带着这个疑问继续看源码是如何创建springSecurityFilterChain对象并返回的。

可以看到这个方法先是调用了apply方法,然后调用build方法返回了创建的对象。

在这里插入图片描述在这里插入图片描述
可以看到apply方法主要是将形参configurer放到了this.configurers这个map里面,而这个configurer就是前面传进来的实参WebSecurityConfigurerAdapter对象。这个对象在build的调用链中的configure()方法中会被使用,主要用于调用configure(WebSecurity web)方法,这个后续章节再做介绍。

在这里插入图片描述
在这里插入图片描述
调用build方法的是WebSecurity类的对象,通过泛型的比对可以发现build方法的返回值类型为Filter,因此必定是调用WebSecurity的performBuild方法。

在这里插入图片描述
可以清楚的看到返回的Filter其实就是FilterChainProxy对象,所以springSecurityFilterChain对象其本质就是FilterChainProxy对象。因此,DelegatingFilterProxy将真正的过滤操作转派给了一个BeanName为springSecurityFilterChain的对象,就是转派给了FilterChainProxy对象!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值