当前位置 : 主页 > 编程语言 > java >

聊聊SpringSecurity的过滤器链的形成

来源:互联网 收集:自由互联 发布时间:2022-09-02
@[TOC] 聊聊SpringSecurity的过滤器链的形成 SpringSecurity的过滤器链是怎么形成的呢?我们一起研究一下。 入口 springboot在启动的时候会加载META-INF/spring.factories下的配置,配置文件中定义了

@[TOC]

聊聊SpringSecurity的过滤器链的形成

SpringSecurity的过滤器链是怎么形成的呢?我们一起研究一下。

入口

springboot在启动的时候会加载META-INF/spring.factories下的配置,配置文件中定义了

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration

也就是说会自动装配SecurityFilterAutoConfiguration这个类,类上有注解:@AutoConfigureAfter(SecurityAutoConfiguration.class)

意思是在加载SecurityAutoConfiguration类之后再加载SecurityFilterAutoConfiguration类,那么我们看一下SecurityAutoConfiguration类

SecurityAutoConfiguration类中导入了SpringBootWebSecurityConfiguration.class, SpringBootWebSecurityConfiguration上有个注解@EnableWebSecurity,表示开启security安全功能,

注解中又导入了WebSecurityConfiguration.class,WebSecurityConfiguration类的功能就是用来生成过滤器链的

WebSecurityConfiguration的springSecurityFilterChain()方法:

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) public Filter springSecurityFilterChain() throws Exception { boolean hasConfigurers = webSecurityConfigurers != null && !webSecurityConfigurers.isEmpty(); if (!hasConfigurers) { WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor .postProcess(new WebSecurityConfigurerAdapter() { }); webSecurity.apply(adapter); } return webSecurity.build(); }

这个方法显然就是构建过滤器链的

深入webSecurity.build()方法会调用AbstractConfiguredSecurityBuilder的doBuild()方法:

@Override protected final O doBuild() throws Exception { synchronized (this.configurers) { this.buildState = BuildState.INITIALIZING; beforeInit(); init(); this.buildState = BuildState.CONFIGURING; beforeConfigure(); configure(); this.buildState = BuildState.BUILDING; O result = performBuild(); this.buildState = BuildState.BUILT; return result; } }

doBuild()方法中调用init()方法,这个方法里会获取到SecurityConfigurer的子类,然后遍历所有的子类调用init()方法

init()方法

在WebSecurityConfigurerAdapter的init()方法中:

@Override public void init(WebSecurity web) throws Exception { HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class); web.securityInterceptor(securityInterceptor); }); }
  • getHttp()方法中添加第一个过滤器链WebAsyncManagerIntegrationFilter类并添加一系列的配置类
  • 再调用web.addSecurityFilterChainBuilder()方法将HttpSecurity实例添加到WebSecurity的securityFilterChainBuilders属性中
  • configure()方法

    init()方法完成后继续执行AbstractConfiguredSecurityBuilder的doBuild()方法中的configure()方法,

    这个方法中会调用具体的SecurityConfigurer实例的configure()方法,而SecurityConfigurer实例的configure()中就会把涉及的过滤器添加到HttpSecurity中

    performBuild()方法

    接下来就会执行AbstractConfiguredSecurityBuilder的performBuild()方法,方法中调用this.filters.sort(this.comparator)来对所有的过滤器进行排序,最终形成的过滤器链:

    WebAsyncManagerIntegrationFilter:集成SecurityContext到Spring异步执行机制中的WebAsyncManager 中

    SecurityContextPersistenceFilter:请求之前使用从SecurityContextRepository}获得的信息填充到SecurityContextHolder中,并在请求完成并清除上下文持有者后将其存储回存储库中。默认情况下,它使用 HttpSessionSecurityContextRepository。

    HeaderWriterFilter:将header信息添加到当前响应中

    CsrfFilter:对于post请求添加csrf的token信息,防止csrf gongji

    LogoutFilter:匹配logout请求,用户退出后清除认证信息

    ValidateCodeFilter:检验码过滤器 自定义的

    UsernamePasswordAuthenticationFilter:用户名密码认证过滤器

    RequestCacheAwareFilter:缓存HttpServletRequest

    SecurityContextHolderAwareRequestFilter:对ServletRequest进行包装

    AnonymousAuthenticationFilter:检测SecurityContextHolder中是否没有Authentication对象,如果为空创建匿名用户存入SecurityContextHolder中

    SessionManagementFilter:限制一个用户开启多个会话的数量

    ExceptionTranslationFilter:异常转换过滤器

    FilterSecurityInterceptor:通过过滤器实现对 HTTP 资源进行安全处理

    然后创建过滤器链的代理对象FilterChainProxy,返回结果

    总结

    这篇文章主要讲了过滤器链的创建过程,入口就是SecurityFilterAutoConfiguration类自动装配,总共有14个过滤器,主要是是通过SecurityConfigurer的实例的configure()方法添加到HttpSecurity对象中的

    上一篇:聊聊SpringSecurity认证流程和授权流程
    下一篇:没有了
    网友评论