SpringSecurity可以通过xml配置或者注解来初始化。其实配置方法不同,初始化过程大致相同。所以我们只通过注解来分析初始化。注解方法的初始化也会根据你项目使用的框架不同而不同。我们只分析SpringBoot框架下SpringSecurity的初始化过程。下面简单列举一下Spring.faciries文件中配置的SpringSecurity相关的自动组装类,只是一个直观的印象,就不一一分析了:org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.servlet.UserDetailsS??erviceAutoConfiguration,\org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfigurationf,\org.raboot.autoconfigure.security.reactive.ReactiveUserDetailsS??erviceAutoConfiguration,\org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\org.springbootframeauto.config.SendGridAutoConfiguration,\org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfigurati上,\org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\org.springframework.boot.autoconfigure.sec.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\SpringSecurity的初始化过程确实复杂,配置类也很多。一开始,有点难下手。因此,我决定从官网的文档入手。参考:https://docs.spring.io/spring…。通过阅读文档,我们知道SpringSecurity是通过过滤器实现的。filter的生效流程如下图所示,其中SpringSecurity会配置n个filter来达到目的:SpringSecurity的多个filter并不是并行插入到Servlet的filter链中,而是插入以过滤器的形式。filter是DelegatingFilterProxy:DelegatingFilterProxy包含了一个由SecurityFilterChain:组成的FilterChainProxy,而正是这个SecurityFilterChain包含了一系列用于实现SpringSecurity的filter过滤器:通过上面的分析,我们知道SpringSecurity是由FilterChainProxy中组装的SecurityFilterChain实现的,SecurityFilterChain包含一系列的过滤器,而正是这些过滤器实现了SpringSecurity的所有功能。因此,第一步从源码的角度分析一下SpringSecurity的SecurityFilterChain的初始化过程。SpringSecurity的配置类不需要像SpringBoot框架下的@EnableWebSecurity那样开启。SpringBoot的自动组装机制会自动启用SpringSecurity的配置。HttpSecutiry类结构SpringSecurity的Filter最终是通过SecurityBuilder创建的,SecurityBuilder持有各个过滤器的configurator,最后通过configurator生成过滤器并组装成SecurityFilterChain。HttpSecurityConfigurationHttpSecurityConfiguration是SpringSecurity的一个重要配置类。它的重要功能之一是初始化HttpSecurity对象。通过httpSecurity()方法创建:@Bean(HTTPSECURITY_BEAN_NAME)@Scope("prototype")HttpSecurityhttpSecurity()throwsException{WebSecurityConfigurerAdapter.LazyPasswordEncoderpasswordEncoder=newWebSecurityConfigurerAdapter.LazyPasswordEncoder(this.context);AuthenticationManagerBuilderauthenticationBuilder=newWebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(this.objectPostProcessor,passwordEncoder);authenticationBuilder.parentAuthenticationManager(authenticationManager());HttpSecurityhttp=newHttpSecurity(this.objectPostProcessor,authenticationBuilder,createSharedObjects());//@formatter:offhttp.csrf(withDefaults()).addFilter(newWebAsyncManagerIntegrationFilter()).exceptionHandling(withDefaults()).headers(withDefaults()).sessionManagement(withDefaults()).securityContext(withDefaults()).requestCache(withDefaults()).anonymous(withDefaults()).servletApi(withDefaults()).apply(newDefaultLoginPageConfigurer<>());http.logout(withDefaults());//@formatter:返回http;}创建一个HttpSecurity对象并调用一系列方法来组装configurers属性。配置器是安全过滤器配置器的集合。SpringSecurity过滤器是通过相应的配置器生成的,所以我们的目光首先关注上面生成配置器的代码。比如http.csrf(withDefaults())调用会生成SpringSecurity的防跨域请求过滤器的配置器,最后通过配置器生成过滤器(后面会分析源码)。SpringSecurity的其他过滤器也是采用上述方法,先生成过滤器配置器,然后配置器生成过滤器,再将过滤器组装到SecurityFilterChain中生效。具体生成configurator的代码就不一一贴出来了。HttpSecurityConfiguration的其他初始化过程暂时忽略。SpringBootWebSecurityConfigurationSpringBootWebSecurityConfiguration只有一个方法defaultSecurityFilterChain,用来创建SecurityFilterChain:@Configuration(proxyBeanMethods=false)@ConditionalOnDefaultWebSecurity@ConditionalOnWebApplication(type=Type.SERVLET)classSpringBootWebSecurityConfiguration{@Bean@Order(SecurityProperties.BASIC_AUTH_ORDER)SecurityFilterChaindefaultSecurityFilterChain(HttpSecurityhttp)throwsException{http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();返回http.build();}}defaultSecurityFilterChain方法有一个参数:HttpSecurity,对象的初始化过程前面我们已经分析过了,我们直接看http.build()。AbstractSecurityBuilder#build()构建方法在父类AbstractSecurityBuilde中实现:@OverridepublicfinalObuild()throwsException{if(this.building.compareAndSet(false,true)){this.object=doBuild();返回这个。目的;}thrownewAlreadyBuiltException("Thisobjecthasalreadybeenbuilt");}AbstractConfiguredSecurityBuilder#doBuilddoBuild方法的一系列调用方式:@OverrideprotectedfinalOdoBuild()throwsException{synchronized(this.configurers){this.buildState=BuildState.INITIALIZING;初始化前();在里面();this.buildState=BuildState.CONFIGURING;配置前();配置();this.buildState=BuildState.BUILDING;Oresult=performBuild();;返回结果;我们关注两个,一个是configure(),另一个是performBuild()。AbstractConfiguredSecurityBuilder#configure()configure方法获取configures,逐一调用其configure方法。configures我们之前分析过HttpSecurityConfiguration的源码,是在HttpSecurity创建之后组装的。privatevoidconfigure()throwsException{Collection
