Spring Security 配置原理

原理解析

前置知识

SecurityBuilder<O>【构建者】
Spring Security 用【构建者】来构建【目标对象】

package org.springframework.security.config.annotation;

public interface SecurityBuilder<O> {

   O build() throws Exception;

}

AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>【可配置的构建者】
实现了【构建者】接口
【可配置的构建者】持有多个 SecurityConfigurer<O, B>【配置器】
通过定义【配置器】对象来影响构建过程,从而达到配置【目标对象】的效果

AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>> 继承了 AbstractSecurityBuilder<O>
AbstractSecurityBuilder 用于限制:一个【构建者】对象只能被用来构建一次,否则抛异常

package org.springframework.security.config.annotation;

public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {

   private AtomicBoolean building = new AtomicBoolean();
   
   private O object;

   @Override
   public final O build() throws Exception {
      if (this.building.compareAndSet(false, true)) {
         this.object = doBuild();
         return this.object;
      }
      throw new AlreadyBuiltException("This object has already been built");
   }
   ...
}

配置逻辑

Spring Security 的功能由 FilterChainProxy 完成

一个 FilterChainProxy 对应多个 SecurityFilterChain
一个经过 FilterChainProxy 的请求最多只会匹配到其中一个 SecurityFilterChain(有可能一个也匹配不到)
一个 SecurityFilterChain 对应多个 Filter
一个 SecurityFilterChain 对应一个 AuthenticationManager
一个 AuthenticationManager 对应多个 AuthenticationProvider

配置 Spring Security 就是构建 FilterChainProxy

  • 为 FilterChainProxy 构建多个 SecurityFilterChain
  • 为每个 SecurityFilterChain 添加多个 Filter
  • 为每个 SecurityFilterChain 构建一个 AuthenticationManager
  • 为每个 AuthenticationManager 添加多个 AuthenticationProvider

涉及的【可配置构建器】

  • WebSecurity(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
    用于构建 FilterChainProxy
    • 实例字段 configurers(多个 SecurityConfigurer<Filter, WebSecurity>)
      1. WebSecurityConfigurerAdapter(SecurityConfigurer<Filter, WebSecurity>)
        • 实例字段 http(HttpSecurity)
        • 实例字段 authenticationBuilder(AuthenticationManagerBuilder)
  • HttpSecurity(AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>)
    用于构建 SecurityFilterChain
    • 实例字段 AbstractConfiguredSecurityBuilder.sharedObjects(一个 Map<Class<?>, Object>)
      其中的 AuthenticationManagerBuilder 就是 WebSecurityConfigurerAdapter.authenticationBuilder
    • 实例字段 configurers
      1. OAuth2ClientConfigurer<HttpSecurity>(SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>)
  • AuthenticationManagerBuilder(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
    用于构建 AuthenticationManager

其中:

  • WebSecurity.configurers
    由 @Autowired WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(…)
    参数注入:@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}")
    其中包括自定义的 WebSecurityConfigurerAdapter 对象
  • WebSecurityConfigurerAdapter.authenticationBuilder
    由 @Autowired WebSecurityConfigurerAdapter.setApplicationContext(ApplicationContext context)
    创建对象:this.authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor,
    passwordEncoder)

客户端程序员可以通过 MySecurityConfigurer extends WebSecurityConfigurerAdapter 来配置 FilterChainProxy

注意:MySecurityConfigurer 必须是 Spring 容器中的 Bean
否则不会加入到 WebSecurity.configurers 中

用到的设计模式

  1. 模板方法
    AbstractSecurityBuilder 的 build() 防止重复构建
    实际调用的是 AbstractConfiguredSecurityBuilder.doBuild()
    而 doBuild() 有多个固定逻辑:init()、configure()、performBuild()
    其中 performBuild() 为抽象方法,由对应构建者重写(如:WebSecurity.performBuild()、HttpSecurity.performBuild())
  2. 构建者
    • WebSecurity(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
      构建 FilterChainProxy
    • HttpSecurity(AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>)
      构建 SecurityFilterChain
    • AuthenticationManagerBuilder(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
      构建 AuthenticationManager
  3. 状态机
    AbstractConfiguredSecurityBuilder.doBuild() 中有多个状态的设置操作
    private BuildState buildState = BuildState.UNBUILT;

配置过程

所有的配置过程,都是在 Spring 装配 Bean 阶段完成的

一、提前装配的 Bean

MySecurityConfig 对象(SecurityConfigurer<Filter, WebSecurity>)
有 @Component 注解,Spring 容器会创建该对象
之后会被加入 WebSecurity.configurers

@Component
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
   ...
}

AuthenticationManagerBuilder 对象(AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>)
WebSecurityConfigurerAdapter.setApplicationContext() 方法中直接 new 出来
赋值给:WebSecurityConfigurerAdapter.authenticationBuilder

package org.springframework.security.config.annotation.web.configuration;

public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
   ...
   private AuthenticationManagerBuilder authenticationBuilder;
   ...
   @Autowired
   public void setApplicationContext(ApplicationContext context) {
      ...
      this.authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor,
         passwordEncoder);
      ...
   }
   ...
}

WebSecurity 对象(AbstractConfiguredSecurityBuilder<Filter, WebSecurity>)
WebSecurityConfiguration.setFilterChainProxySecurityConfigurer() 方法中直接被 new 出来
上边的 MySecurityConfig 对象会在这个方法中被加入到 WebSecurity.configurers

package org.springframework.security.config.annotation.web.configuration;

@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
   
   private WebSecurity webSecurity;
   ...
   // 设置 webSecurity
   @Autowired(required = false)
   public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
      @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
      throws Exception {
      
      this.webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
      ...
      for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
         this.webSecurity.apply(webSecurityConfigurer);
      }
      this.webSecurityConfigurers = webSecurityConfigurers;
   }
}

二、开始构建

只要引入了 Spring Security 包,类路径下就会有 WebSecurityConfiguration

package org.springframework.security.config.annotation.web.configuration;

@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration
   implements ImportAware, BeanClassLoaderAware {
   
   private WebSecurity webSecurity;
   ...
   // 构建 FilterChainProxy
   @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
   public Filter springSecurityFilterChain() throws Exception {
      ...
      return this.webSecurity.build(); //(1-35)
   }
   ...
}

WebSecurity

package org.springframework.security.config.annotation.web.builders;

public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
   implements SecurityBuilder<Filter>, ApplicationContextAware {
   ...
   private final List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders = new ArrayList<>();
   ...
   public WebSecurity addSecurityFilterChainBuilder(
      SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder) { // -->(19) // 201
        
      this.securityFilterChainBuilders.add(securityFilterChainBuilder);
      return this;
   }
   ...
   @Override
   protected Filter performBuild() throws Exception { // -->(22-35) // 272
      Assert.state(!this.securityFilterChainBuilders.isEmpty(),
         () -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
            + "Typically this is done by exposing a SecurityFilterChain bean "
            + "or by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
            + "More advanced users can invoke " + WebSecurity.class.getSimpleName()
            + ".addSecurityFilterChainBuilder directly");
      int chainSize = this.ignoredRequests.size() + this.securityFilterChainBuilders.size();
      List<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);
      for (RequestMatcher ignoredRequest : this.ignoredRequests) {
         securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
      }
      for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {
         // HttpSecurity.build() 构建 SecurityFilterChain,并加入 FilterChainProxy.filterChains
         securityFilterChains.add(securityFilterChainBuilder.build()); //(23-35)
      }
      // new 了一个 FilterChainProxy 对象,并注入 FilterChainProxy.filterChains
      FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
      if (this.httpFirewall != null) {
         filterChainProxy.setFirewall(this.httpFirewall);
      }
      if (this.requestRejectedHandler != null) {
         filterChainProxy.setRequestRejectedHandler(this.requestRejectedHandler);
      }
      filterChainProxy.afterPropertiesSet();

      Filter result = filterChainProxy;
      if (this.debugEnabled) {
         this.logger.warn("\n\n" + "********************************************************************\n"
            + "**********        Security debugging is enabled.       *************\n"
            + "**********    This may include sensitive information.  *************\n"
            + "**********      Do not use in a production system!     *************\n"
            + "********************************************************************\n\n");
         result = new DebugFilter(filterChainProxy);
      }
      this.postBuildAction.run();
      return result;
   }
   ...
}

AbstractConfiguredSecurityBuilder<Filter, WebSecurity>

package org.springframework.security.config.annotation;

public abstract class AbstractConfiguredSecurityBuilder<Filter, WebSecurity>
   extends AbstractSecurityBuilder<Filter> {
   
   ...
   private final LinkedHashMap<Class<? extends SecurityConfigurer<Filter, WebSecurity>>, List<SecurityConfigurer<Filter, WebSecurity>>>
      configurers = new LinkedHashMap<>();
   ...
   @Override
   protected final Filter doBuild() throws Exception { // -->(2-35) // 296
      synchronized (this.configurers) {
         this.buildState = BuildState.INITIALIZING;
         beforeInit();
         // 循环调用 configurers 的 init() 方法
         init(); //(3-19)
         this.buildState = BuildState.CONFIGURING;
         beforeConfigure();
         // 循环调用 configurers 的 configure() 方法
         configure(); //(20-21)
         this.buildState = BuildState.BUILDING;
         // WebSecurity.performBuild()
         Filter result = performBuild(); //(22-35)
         this.buildState = BuildState.BUILT;
         return result;
      }
   }
   ...
   private void init() throws Exception { // -->(3-19) // 335
      Collection<SecurityConfigurer<Filter, WebSecurity>> configurers = getConfigurers();
      for (SecurityConfigurer<Filter, WebSecurity> configurer : configurers) {
         configurer.init((WebSecurity) this); //(4-19)
      }
      for (SecurityConfigurer<Filter, WebSecurity> configurer : this.configurersAddedInInitializing) {
         configurer.init((WebSecurity) this);
      }
   }

   private void configure() throws Exception { // -->(20-21) // 346
      Collection<SecurityConfigurer<Filter, WebSecurity>> configurers = getConfigurers();
      for (SecurityConfigurer<Filter, WebSecurity> configurer : configurers) {
         // MySecurityConfig.configure(WebSecurity web)
         configurer.configure((WebSecurity) this); //(21)
      }
   }

   private Collection<SecurityConfigurer<Filter, WebSecurity>> getConfigurers() {
      List<SecurityConfigurer<Filter, WebSecurity>> result = new ArrayList<>();
      for (List<SecurityConfigurer<Filter, WebSecurity>> configs : this.configurers.values()) {
         result.addAll(configs);
      }
      return result;
   }
   ...
}

AbstractSecurityBuilder

package org.springframework.security.config.annotation;

public abstract class AbstractSecurityBuilder<Filter> implements SecurityBuilder<Filter> {

   private AtomicBoolean building = new AtomicBoolean();
   
   private Filter object;
   
   @Override
   public final Filter build() throws Exception { // -->(1-35)
      // 防止重复构建
      if (this.building.compareAndSet(false, true)) {
         this.object = doBuild(); //(2-35)
         return this.object;
      }
      throw new AlreadyBuiltException("This object has already been built");
   }
   ...
   protected abstract Filter doBuild() throws Exception;

}

WebSecurityConfigurerAdapter

package org.springframework.security.config.annotation.web.configuration;

@Order(100)
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {
   ...
   private AuthenticationConfiguration authenticationConfiguration;
    
   // 用于构建 SecurityFilterChain 的 AuthenticationManager
   private AuthenticationManagerBuilder authenticationBuilder;
    
   private AuthenticationManagerBuilder localConfigureAuthenticationBldr;
    
   private boolean disableLocalConfigureAuthenticationBldr;
    
   private boolean authenticationManagerInitialized;

   // SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager
   private AuthenticationManager authenticationManager;
   ...
   private HttpSecurity http;
   ...
   /*
   可重写,用于配置 this.localConfigureAuthenticationBldr
   如果重写了该方法,this.disableLocalConfigureAuthenticationBldr 不会被设置为 true
   SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager 会用 this.localConfigureAuthenticationBldr 构建
   否则,会使用 this.authenticationConfiguration.getAuthenticationManager() 获取父 AuthenticationManager
   即 AuthenticationConfiguration.getAuthenticationManager()
   */
   protected void configure(AuthenticationManagerBuilder auth) throws Exception { // -->(7) // 188
      this.disableLocalConfigureAuthenticationBldr = true;
   }

   protected final HttpSecurity getHttp() throws Exception { // -->(5-18) // 198
      if (this.http != null) {
         return this.http;
      }
      AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher();
      this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
      // 获取 SecurityFilterChain 的 AuthenticationManager 的父 AuthenticationManager
      AuthenticationManager authenticationManager = authenticationManager(); //(6-8)
      this.authenticationBuilder.parentAuthenticationManager(authenticationManager); //(9)
      Map<Class<?>, Object> sharedObjects = createSharedObjects();
      this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects); //(10-13)
      if (!this.disableDefaults) {
         applyDefaultConfiguration(this.http);
         ClassLoader classLoader = this.context.getClassLoader();
         List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
            .loadFactories(AbstractHttpConfigurer.class, classLoader);
         for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
            // 将一个默认 configurers 列表加入到 this.http 的 configurers 中
            this.http.apply(configurer); //(14)
         }
      }
      /*
      这一步用来添加和配置 HttpSecurity.configurers
      一个 configurer 对应 SecurityFilterChain 中的若干个 Filter 
      */
      configure(this.http); //(15-18)
      return this.http;
   }
   ...
   protected AuthenticationManager authenticationManager() throws Exception { // -->(6-8) // 262
      if (!this.authenticationManagerInitialized) {
         configure(this.localConfigureAuthenticationBldr); //(7)
         if (this.disableLocalConfigureAuthenticationBldr) {
            this.authenticationManager = this.authenticationConfiguration.getAuthenticationManager(); //(8)
         }
         else {
            this.authenticationManager = this.localConfigureAuthenticationBldr.build();
         }
         this.authenticationManagerInitialized = true;
      }
      return this.authenticationManager;
   }
   ...
   @Override
   public void init(WebSecurity web) throws Exception { // -->(4-19) // 314
      // 创建 HttpSecurity(SecurityBuilder<DefaultSecurityFilterChain>)
      HttpSecurity http = getHttp(); //(5-18)
      // 把 HttpSecurity 加入 WebSecurity(SecurityBuilder<Filter>)的 securityFilterChainBuilders
      web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { //(19)
         FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
         web.securityInterceptor(securityInterceptor);
      });
   }
   ...
}

AuthenticationConfiguration

package org.springframework.security.config.annotation.authentication.configuration;

@Configuration(proxyBeanMethods = false)
@Import(ObjectPostProcessorConfiguration.class)
public class AuthenticationConfiguration {
   ...
   public AuthenticationManager getAuthenticationManager() throws Exception { // -->(8) // 110
      if (this.authenticationManagerInitialized) {
         return this.authenticationManager;
      }
      AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean(AuthenticationManagerBuilder.class);
      if (this.buildingAuthenticationManager.getAndSet(true)) {
         return new AuthenticationManagerDelegator(authBuilder);
      }
      for (GlobalAuthenticationConfigurerAdapter config : this.globalAuthConfigurers) {
         authBuilder.apply(config);
      }
      this.authenticationManager = authBuilder.build();
      if (this.authenticationManager == null) {
         this.authenticationManager = getAuthenticationManagerBean();
      }
      this.authenticationManagerInitialized = true;
      return this.authenticationManager;
   }
   ...
}

HttpSecurity

package org.springframework.security.config.annotation.web.builders;

public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
   implements SecurityBuilder<DefaultSecurityFilterChain>, HttpSecurityBuilder<HttpSecurity> {
   ...
   private List<OrderedFilter> filters = new ArrayList<>();
   ...
   public HttpSecurity(ObjectPostProcessor<Object> objectPostProcessor,
      AuthenticationManagerBuilder authenticationBuilder, Map<Class<?>, Object> sharedObjects) { // -->(10-13) // 154
        
      super(objectPostProcessor);
      Assert.notNull(authenticationBuilder, "authenticationBuilder cannot be null");
      setSharedObject(AuthenticationManagerBuilder.class, authenticationBuilder); //(11-12)
      for (Map.Entry<Class<?>, Object> entry : sharedObjects.entrySet()) {
         setSharedObject((Class<Object>) entry.getKey(), entry.getValue());
      }
      ApplicationContext context = (ApplicationContext) sharedObjects.get(ApplicationContext.class);
      this.requestMatcherConfigurer = new RequestMatcherConfigurer(context); //(13)
   }
   ...
   public HttpSecurity oauth2Client(Customizer<OAuth2ClientConfigurer<HttpSecurity>> oauth2ClientCustomizer)
      throws Exception { // -->(16-18) // 2382

      /*
      getOrApply():
      AbstractConfiguredSecurityBuilder.configurers 中有 OAuth2ClientConfigurer<HttpSecurity> 对象则获取
      没有则将 new 的 OAuth2ClientConfigurer<HttpSecurity> 对象加入 AbstractConfiguredSecurityBuilder.configurers
      oauth2ClientCustomizer 是客户端程序员创建的匿名内部类实现,用来根据需求调用 OAuth2ClientConfigurer<HttpSecurity> 的 API 进行配置
      */
      oauth2ClientCustomizer.customize(getOrApply(new OAuth2ClientConfigurer<>())); //(17-18)
      return HttpSecurity.this;
   }
   ...
   @Override
   public <C> void setSharedObject(Class<C> sharedType, C object) { // -->(11-12) // 2608
      super.setSharedObject(sharedType, object); //(12)
   }
   ...
   @Override
   protected DefaultSecurityFilterChain performBuild() { // 2618
      this.filters.sort(OrderComparator.INSTANCE);
      List<Filter> sortedFilters = new ArrayList<>(this.filters.size());
      for (Filter filter : this.filters) {
         sortedFilters.add(((OrderedFilter) filter).filter);
      }
      return new DefaultSecurityFilterChain(this.requestMatcher, sortedFilters);
   }
	
   @Override
   public HttpSecurity authenticationProvider(AuthenticationProvider authenticationProvider) { // -->(29-32) // 2628
      /*
      (30-31)从 AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>.sharedObjects 获取 AuthenticationManagerBuilder 对象
         就是 WebSecurityConfigurerAdapter.authenticationBuilder
         new HttpSecurity() 时加入的 AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>.sharedObjects
      (32)将 AuthenticationProvider 加入 AuthenticationManagerBuilder.authenticationProviders
      */
      getAuthenticationRegistry() //(30-31)
         .authenticationProvider(authenticationProvider); //(32)
      return this;
   }
   ...
   private AuthenticationManagerBuilder getAuthenticationRegistry() { // -->(30-31) // 2639
      return getSharedObject(AuthenticationManagerBuilder.class); //(31)
   }
   ...
   private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> C getOrApply(C configurer)
      throws Exception { // -->(17-18) // 2993
		
      C existingConfig = (C) getConfigurer(configurer.getClass()); //(18)
      if (existingConfig != null) {
         return existingConfig;
      }
      return apply(configurer);
   }
   ...
}

AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>

public abstract class AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
   extends AbstractSecurityBuilder<DefaultSecurityFilterChain> {
   ...
   private final LinkedHashMap<Class<? extends SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>>, List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>>>
      configurers = new LinkedHashMap<>();
   ...
   private final Map<Class<?>, Object> sharedObjects = new HashMap<>(); // 62
   ...
   public <C> void setSharedObject(Class<C> sharedType, C object) { // -->(12) // 148
      this.sharedObjects.put(sharedType, object);
   }
	
   public <C> C getSharedObject(Class<C> sharedType) { // -->(31) // 158
      return (C) this.sharedObjects.get(sharedType);
   }
   ...
   public <C extends SecurityConfigurer<O, B>> C getConfigurer(Class<C> clazz) { // -->(18) // 234
      List<SecurityConfigurer<O, B>> configs = this.configurers.get(clazz);
      if (configs == null) {
         return null;
      }
      Assert.state(configs.size() == 1,
         () -> "Only one configurer expected for type " + clazz + ", but got " + configs);
      return (C) configs.get(0);
   }
   ...
   @Override
   protected final DefaultSecurityFilterChain doBuild() throws Exception { // -->(24-35) // 296
      synchronized (this.configurers) {
         this.buildState = BuildState.INITIALIZING;
         beforeInit();
         // 循环调用 configurers 的 init() 方法
         init(); //(25-32)
         this.buildState = BuildState.CONFIGURING;
         beforeConfigure();
         // 循环调用 configurers 的 configure() 方法
         configure(); //(33-35)
         this.buildState = BuildState.BUILDING;
         // HttpSecurity.performBuild()
         DefaultSecurityFilterChain result = performBuild();
         this.buildState = BuildState.BUILT;
         return result;
      }
   }
   ...
   private void init() throws Exception { // -->(25-32) // 335
      Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configurers = getConfigurers();
      for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : configurers) {
         /*
         OAuth2ClientConfigurer<HttpSecurity>.init(HttpSecurity)
         向 AuthenticationManagerBuilder.authenticationProviders 加入:OAuth2AuthorizationCodeAuthenticationProvider 
         */
         configurer.init((HttpSecurity) this); //(26-32)
      }
      for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : this.configurersAddedInInitializing) {
         configurer.init((HttpSecurity) this);
      }
   }

   private void configure() throws Exception { // -->() // -->(33-35) // 346
      Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configurers = getConfigurers();
      for (SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> configurer : configurers) {
         /*
         OAuth2ClientConfigurer<HttpSecurity>.configure(HttpSecurity)
         向 HttpSecurity.filters 加入:
         OAuth2AuthorizationRequestRedirectFilter、OAuth2AuthorizationCodeGrantFilter
         */
         configurer.configure((HttpSecurity) this); //(34-35)
      }
   }

   private Collection<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> getConfigurers() {
      List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> result = new ArrayList<>();
      for (List<SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity>> configs : this.configurers.values()) {
         result.addAll(configs);
      }
      return result;
   }
   ...
}

AbstractSecurityBuilder

package org.springframework.security.config.annotation;

public abstract class AbstractSecurityBuilder<DefaultSecurityFilterChain> implements SecurityBuilder<DefaultSecurityFilterChain> {

   private AtomicBoolean building = new AtomicBoolean();
   
   private DefaultSecurityFilterChain object;
   
   @Override
   public final DefaultSecurityFilterChain build() throws Exception { // -->(23-35)
      // 防止重复构建
      if (this.building.compareAndSet(false, true)) {
         this.object = doBuild(); //(24-35)
         return this.object;
      }
      throw new AlreadyBuiltException("This object has already been built");
   }
   ...
   protected abstract DefaultSecurityFilterChain doBuild() throws Exception;

}
package org.springframework.security.config.annotation.web.configurers.oauth2.client;

public final class OAuth2ClientConfigurer<HttpSecurity>
   extends AbstractHttpConfigurer<OAuth2ClientConfigurer<HttpSecurity>, HttpSecurity> {
    
   private AuthorizationCodeGrantConfigurer authorizationCodeGrantConfigurer = new AuthorizationCodeGrantConfigurer();
   ...
   @Override
   public void init(HttpSecurity builder) { // -->(26-32) // 156
      this.authorizationCodeGrantConfigurer.init(builder); //(27-32)
   }
	
   @Override
   public void configure(HttpSecurity builder) { // -->(34-35) // 161
      this.authorizationCodeGrantConfigurer.configure(builder); //(35)
   }
	
   public final class AuthorizationCodeGrantConfigurer { // 168
	  ...
	  private void init(B builder) { // -->(27-32) // 227
         OAuth2AuthorizationCodeAuthenticationProvider
            authorizationCodeAuthenticationProvider = new OAuth2AuthorizationCodeAuthenticationProvider(
               getAccessTokenResponseClient()); //(28)
         builder.authenticationProvider(postProcess(authorizationCodeAuthenticationProvider)); //(29-32)
      }

      private void configure(HttpSecurity builder) { // -->(35) // 233
         OAuth2AuthorizationRequestRedirectFilter
            authorizationRequestRedirectFilter = createAuthorizationRequestRedirectFilter(builder);
         builder.addFilter(postProcess(authorizationRequestRedirectFilter));
         OAuth2AuthorizationCodeGrantFilter
            authorizationCodeGrantFilter = createAuthorizationCodeGrantFilter(builder);
         builder.addFilter(postProcess(authorizationCodeGrantFilter));
      }
      ...
      private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> getAccessTokenResponseClient() { // -->(28) // 282
         if (this.accessTokenResponseClient != null) {
            return this.accessTokenResponseClient;
         }
         return new DefaultAuthorizationCodeTokenResponseClient();
      }
   }
   ...
}

MySecurityConfig

@Component
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception { // -->(15-18)
      http.oauth2Client(oAuth2ClientConfigurer -> {}); //(16-18)
   }
    
   @Override
   public void configure(WebSecurity web) { // -->(21)
      /*
      在 WebSecurity.ignoredRequestRegistry 上注册要忽略的 URL 模式
      匹配上的请求,会被 FilterChainProxy 忽略
      */
      web.ignoring().antMatchers("/webjars/**");
   }
    
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值