3、spring security流程解读之WebSecurityConfiguration

使用WebSecurity创建了FilterChainProxy拦截的链路代理类,对请求进行拦截。可以通过继承WebSecurityConfigurerAdapter对其进行任意的配置

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
    //判断是否有WebSecurityConfigurer的实现类。
    //如果没有,则创建默认的WebSecurityConfigurerAdapter
   boolean hasConfigurers = webSecurityConfigurers != null
         && !webSecurityConfigurers.isEmpty();
   if (!hasConfigurers) {
      WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
            .postProcess(new WebSecurityConfigurerAdapter() {
            });
      webSecurity.apply(adapter);
   }
   return webSecurity.build();
}

这里着重看下springSecurityFilterChain()这个方法,webSecurityConfigurers集合是获取了WebSecurityConfigurer的实现类,而WebSecurityConfigurerAdapter实现了该接口,所以我们只需要继承WebSecurityConfigurerAdapter 该方法会通过WebSecurity构建出一个FilterChainProxy,也是spring security拦截器的核心入口。

首先看下WebSecurity的类结构图

WebSecurity.build():

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");
}

查看源码发现,build()内部是调用了doBuild()方法

protected final O doBuild() throws Exception {
   synchronized (configurers) {
      buildState = BuildState.INITIALIZING;

      beforeInit();
      init();

      buildState = BuildState.CONFIGURING;

      beforeConfigure();
      configure();

      buildState = BuildState.BUILDING;

      O result = performBuild();

      buildState = BuildState.BUILT;

      return result;
   }
}

大致可以分为7步骤

1、修改构建状态为构建中

2、初始化前 beforeInit()。该方法内是空的,如果在初始化前需要什么操作可以重写此方法

3、初始化 init()。这里是调用了SecurityConfigurer实现类的init()方法。WebSecurityConfigurerAdapter实现了该接口。获取HttpSecurity以及设置WebSecurity的拦截器FilterSecurityInterceptor

protected final HttpSecurity getHttp() throws Exception {
   if (http != null) {
      return http;
   }

   DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
         .postProcess(new DefaultAuthenticationEventPublisher());
   //1、设置认证事件发布器
   localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);

  //2、获取AuthenticationManager对象作为authenticationBuilder的父级
   AuthenticationManager authenticationManager = authenticationManager();
   authenticationBuilder.parentAuthenticationManager(authenticationManager); 
   //3、设置authenticationBuilder的认证事件发布器
   authenticationBuilder.authenticationEventPublisher(eventPublisher);
   //4、创建Map类型分享对象
   Map<Class<?>, Object> sharedObjects = createSharedObjects();

   //5、创建HttpSecurity,可以配置基于web的安全性请求
   http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
         sharedObjects);
   //6、是否禁用默认配置,如果为false,则配置默认的http设置   
   if (!disableDefaults) {
      // @formatter:off
      http
         .csrf().and() //跨域请求伪造验证
         .addFilter(new WebAsyncManagerIntegrationFilter())
         .exceptionHandling().and() //异常执行器,会创建ExceptionTranslationFilter
         .headers().and() //HeaderWriterFilter
         .sessionManagement().and() //SessionManagementFilter
         .securityContext().and() //SecurityContextPersistenceFilter
         .requestCache().and() //RequestCacheAwareFilter
         .anonymous().and() //AnonymousAuthenticationFilter
         .servletApi().and() //SecurityContextHolderAwareRequestFilter
         .apply(new DefaultLoginPageConfigurer<>()).and() //DefaultLoginPageGeneratingFilter
         .logout(); //LogoutFilter
      // @formatter:on
      ClassLoader classLoader = this.context.getClassLoader();
      //7、从配置文件中加载AbstractHttpConfigurer
      List<AbstractHttpConfigurer> defaultHttpConfigurers =
            SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);

      for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
         http.apply(configurer);
      }
   }
   //8、调用configure(HttpSecurity),子类可以重写该方法对http进行配置
   configure(http);
   return http;
}

4、配置前。 默认空

5、配置。调用SecurityConfigurer的configure(WebSecurity)

6、构建FilterChainProxy

7、修改构建状态为已构建

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值