Análisis de código fuente del proceso de inicio aproximado predeterminado de Spring Security

Análisis de código fuente del proceso de inicio aproximado predeterminado de Spring Security

Comprender el proceso básico.

entender primerospring.factories

fábricas.de.primavera

org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
  1. SecurityAutoConfiguration es la clase de configuración principal, principalmente explicamos esta clase
  2. UserDetailsServiceAutoConfiguration se usa para establecer la contraseña predeterminada, que se configurará cuando SecurityAutoConfiguration configure HttpSecurity, por lo que no entraremos en detalles
  3. SecurityFilterAutoConfiguration no habla
  4. Los dos últimos son seguridad OAuth, sin mencionar

Principalmente analizamos SecurityAutoConfigurationque es una clase de configuración automática, afectada por ella EnableWebSecurit , será importada HttpSecurityConfigurationy cargada antes de cargarWebSecurityConfiguration

Su orden de acción es: HttpSecurityConfigurationconfiguración HttpSecurityConfiguration, WebSecurityConfigurationconfiguraciónWebSecurity

El proceso también se trata principalmente de: configuración HttpSecurity--> configurar el básico predeterminado SecurityFilterChain --> configurar WebSecurity--> configurar el finalSecurityFilterChain

También puede entenderse como: ¿cómo crear el definitivo SecurityFilterChain?

Anotaciones EnableWebSecurity y EnableGlobalAuthentication

@Import({
    
     WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class,
      HttpSecurityConfiguration.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
    
    }
@Import(AuthenticationConfiguration.class)
@Configuration
public @interface EnableGlobalAuthentication {
    
    }

configuraciónHttpSecurity

Desde HttpSecurityConfigurationel principio, esta clase es la clase de configuración básica de HttpSecurity, la configuración es la siguiente:

HttpSecurityConfiguration.java

@Autowired
void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
    
    
    this.authenticationConfiguration = authenticationConfiguration;
}//1
@Bean(HTTPSECURITY_BEAN_NAME)
@Scope("prototype")
HttpSecurity httpSecurity() throws Exception {
    
    
   WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(
         this.context);//2
   AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(
         this.objectPostProcessor, passwordEncoder);//3
   authenticationBuilder.parentAuthenticationManager(authenticationManager());//4
   HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());//5
   http
      .csrf(withDefaults())
      .addFilter(new WebAsyncManagerIntegrationFilter())
      .exceptionHandling(withDefaults())
      .headers(withDefaults())
      .sessionManagement(withDefaults())
      .securityContext(withDefaults())
      .requestCache(withDefaults())
      .anonymous(withDefaults())
      .servletApi(withDefaults())
      .apply(new DefaultLoginPageConfigurer<>());
   http.logout(withDefaults());//6
   return http;
}
  1. Inyección de dependencia de una configuración de autenticación, precargando la configuración de autenticación que debe configurarse automáticamente antes,

    Esta clase crea tres objetos Bean importantes: AuthenticationManagerBuild, InitializeUserDetailsBeanManagerConfigurer e InitializeAuthenticationProviderBeanManagerConfigurer

    utilizado respectivamente

    • Cree el administrador de autenticación
    • Se utiliza para inicializar UserDetailsServiceAutoConfiguration en spring.factories, su función es proporcionar un nombre de usuario y una contraseña predeterminados,
    • Inicializar el administrador de autenticación de usuarios (ProviderManager)
  2. Crear un cargador de contraseña perezoso

  3. Crear un generador de administrador de autenticación

  4. Cree un administrador de autenticación

    Configuración de autenticación.java

    public AuthenticationManager getAuthenticationManager() throws Exception {
           
           
       //...
       for (GlobalAuthenticationConfigurerAdapter config : this.globalAuthConfigurers) {
           
           
          authBuilder.apply(config);
       }//1
       this.authenticationManager = authBuilder.build();//2
       //...
       return this.authenticationManager;
    }
    
    1. El constructor usa la configuración de autenticación global, que se mencionó anteriormente al crear AuthenticationConfiguration

    2. Cree el administrador de autenticación

      Mire directamente el último doBuild()

      AbstractConfiguredSecurityBuilder

      protected final O doBuild() throws Exception {
                
                
         synchronized (this.configurers) {
                
                
            this.buildState = BuildState.INITIALIZING;
            beforeInit();//1
            init();//2
            this.buildState = BuildState.CONFIGURING;
            beforeConfigure();//3
            configure();//4
            this.buildState = BuildState.BUILDING;
            O result = performBuild();//5
            this.buildState = BuildState.BUILT;
            return result;
         }
      }
      
      1. Operación antes de la inicialización

      2. Inicializar el configurador

      3. Operación antes de la configuración

      4. Configura el configurador, hay muchos configuradores, así que no voy a hablar de eso, el proceso de configuración es el siguiente:

        AbstractConfiguredSecurityBuilder

        private void configure() throws Exception {
                     
                     
           Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
           for (SecurityConfigurer<O, B> configurer : configurers) {
                     
                     
              configurer.configure((B) this);
           }
        }
        
      5. empezar a construir

        Este método crea y devuelve un PrivideManager

        AuthenticationManagerBuilder.java

        protected ProviderManager performBuild() throws Exception {
                     
                     
           ProviderManager providerManager = new ProviderManager(this.authenticationProviders,
                 this.parentAuthenticationManager);
           return providerManager;
        }
        
  5. Crear , inyectar lo HttpSecurityanteriorPrividerHttpSecurity

  6. HttpSecurityConfigurar el configurador básico


configuraciónSecurityFilterChain

Una vez completada la configuración predeterminada HttpSecurity, comenzará a configurar el valor predeterminado SecurityFilterChain,

Veamos las clases SecurityAutoConfigurationimportadas.SpringBootWebSecurityConfiguration

SpringBootWebSecurityConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity//1
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
    
    
   @Bean
   @Order(SecurityProperties.BASIC_AUTH_ORDER)
   SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    
    
      http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
      return http.build();//2
   }

}
  1. Esta clase solo se configurará cuando se cumpla la WebSecurity predeterminada, de la siguiente manera:

    @Conditional(DefaultWebSecurityCondition.class)//1
    public @interface ConditionalOnDefaultWebSecurity {
           
           }
    class DefaultWebSecurityCondition extends AllNestedConditions {
           
           
    	DefaultWebSecurityCondition() {
           
           super(ConfigurationPhase.REGISTER_BEAN);}
    	@ConditionalOnClass({
           
            SecurityFilterChain.class, HttpSecurity.class })
    	static class Classes {
           
           }//2
    	@ConditionalOnMissingBean({
           
            WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
    	static class Beans {
           
           }//3
    }
    
    
    1. cumplir con DefaultWebSecurityConditionlas condiciones
    2. Satisfecho con SecurityFilterChain.classsus HttpSecurity.classdos clases
    3. Conoce la falta WebSecurityConfigurerAdapter.classde SecurityFilterChain.classdos beans, y la configuración de seguridad predeterminada no tiene estas dos clases
  2. Cree la SecurityFilterChain básica predeterminada, donde SecurityFilterChain tiene quince filtros básicos:

    Quince filtros básicos


configuraciónWebSecurity

Después de configurar el SecurityFilterChain básico predeterminado, se configuraráWebSecurity

vemos WebSecurityConfigurationclase

Primero mira cómo está configurado WebSecurity, de la siguiente manera:

WebrSecurityConfiguration.java

@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
      @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)//1
      throws Exception {
    
    
   this.webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
   webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);//2
   Integer previousOrder = null;
   Object previousConfig = null;
   for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
    
    
      Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
      previousOrder = order;
      previousConfig = config;
   }//3
   for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
    
    
      this.webSecurity.apply(webSecurityConfigurer);
   }//4
   this.webSecurityConfigurers = webSecurityConfigurers;
}
  1. Primero observe los parámetros formales con anotaciones @Value, esta anotación obtiene todos los configurados previamente WebSeucurityConfigurer(es decir, personalizados WebSecurityConfigurer), y pasará todos los configuradores a los creados actualmente a continuación WebSecurity.
  2. crearWebSecurity
  3. Ordenar obtenido (personalizado)SecurityConfigurer
  4. Pase el SecurityConfigurerconfigurador obtenido (personalizado) al WebSecuirty actual, aplique los usos del configurador, no hace falta decir

Configurar la finalFilterChainProxy

Después de la configuración WebSecurity, básica SecurityFilterChain, configurará la finalSecurityFilterChain

WebSecurityConfiguration.java

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
    
    
   if (!hasConfigurers && !hasFilterChain) {
    
    
      WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
            .postProcess(new WebSecurityConfigurerAdapter() {
    
    
            });
      this.webSecurity.apply(adapter);
   }//1
   for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
    
    
      this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain);
      for (Filter filter : securityFilterChain.getFilters()) {
    
    
         if (filter instanceof FilterSecurityInterceptor) {
    
    
            this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter);
            break;
         }
      }
   }//2
   for (WebSecurityCustomizer customizer : this.webSecurityCustomizers) {
    
    
      customizer.customize(this.webSecurity);
   }//3
   return this.webSecurity.build();//4
}
  1. FilterChainCrear si no está presente FilterChain, ya sea personalizado o predeterminado, generalmente conFilterChain

  2. WebSecurityconfiguraciónFilterSecurityInterceptor

  3. Configurar personalizado WebSecurity, la clase personalizada necesita implementar WebSecurityCustomizerla interfaz

    WebSecurityConfiguration.java

    @Autowired(required = false)
    void setWebSecurityCustomizers(List<WebSecurityCustomizer> webSecurityCustomizers) {
            
            
       this.webSecurityCustomizers = webSecurityCustomizers;
    }
    
  4. Volver a la final reconfigurada WebSecuriity( SecurityFilterChainversión final)

    buid()No hablaré mucho sobre el método, AuthenticationConfigurationtambién lo mencioné al configurar [HttpSecurity] (# Configure HttpSecurity) antes, aquí analizamos principalmente los diferentes métodos AbstractConfiguredSecurityBuilderde herenciaperformBuild()

    WebSecurity.java

    @Override
    protected Filter performBuild() throws Exception {
           
           
       int chainSize = this.ignoredRequests.size() + this.securityFilterChainBuilders.size();
       List<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);
       List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries = new ArrayList<>();
       for (RequestMatcher ignoredRequest : this.ignoredRequests) {
           
           
          SecurityFilterChain securityFilterChain = new DefaultSecurityFilterChain(ignoredRequest);
          securityFilterChains.add(securityFilterChain);
          requestMatcherPrivilegeEvaluatorsEntries
                .add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
       }
       for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {
           
           
          SecurityFilterChain securityFilterChain = securityFilterChainBuilder.build();
          securityFilterChains.add(securityFilterChain);
          requestMatcherPrivilegeEvaluatorsEntries
                .add(getRequestMatcherPrivilegeEvaluatorsEntry(securityFilterChain));
       }
       if (this.privilegeEvaluator == null) {
           
           
          this.privilegeEvaluator = new RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
                requestMatcherPrivilegeEvaluatorsEntries);
       }
       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;
        
       this.postBuildAction.run();
       return result;
    }
    

    El análisis muestra que la función de este método es agregar el filtro SecurityFilterChain predeterminado y el filtro WebSecurity al FilterChainProxy recién creado y devolver


fin

En este punto, Spring Security se basa aproximadamente en el proceso de inicio. El análisis del código fuente ha terminado.

Supongo que te gusta

Origin blog.csdn.net/HHoao/article/details/124573922
Recomendado
Clasificación