Article directory
-
- doBuild()
-
- init()
- configure()
- performBuild()
- Secondary doBuild
-
- secondary init
- secondary configure()
- Secondary performBuild()
- Returns the first performBuild
- Summarize:
The process of springSecurity injecting springSecurityFilterChain:
If there is no webSecurityConfigure in the memory and no securityFilterChain, then create a new Adapter object. Here, there is a webSecurityConfigure in the memory, and its source is the manually added configuration class, as follows:
// Then execute the code: securityFilterChains length is 0, do not enter the inside of the for loop for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {<!-- --> this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain); for (Filter filter : securityFilterChain. getFilters()) {<!-- --> if (filter instanceof FilterSecurityInterceptor) {<!-- --> this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter); break; } } } // The length of webSecurityCustomizers is also 0 for (WebSecurityCustomizer customizer : this. webSecurityCustomizers) {<!-- --> customizer. customize(this. webSecurity); } // Focus on executing the build method return this. webSecurity. build();
Then enter:
Continue to the doBuild() method:
doBuild()
// Enter doBuild() in the AbstractConfiguredSecurityBuilder class @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; } }
init()
private void init() throws Exception {<!-- --> Collection<SecurityConfigurer<O, B>> configurers = getConfigurers(); // The length of configurers is 1, which is the previous custom configuration class object: SpringSecurityTest object for (SecurityConfigurer<O, B> configurer : configurers) {<!-- --> configurer.init((B) this); } // this.configurersAddedInInitializing length=0 for (SecurityConfigurer<O, B> configurer : this.configurersAddedInInitializing) {<!-- --> configurer.init((B) this); } }
Enter the init method in the for loop: the next step is to initialize HttpSecurity
// web.addSecurityFilterChainBuilder() Enter the WebSecurity class to execute the addSecurityFilterChainBuilder() method: public WebSecurity addSecurityFilterChainBuilder( SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder) {<!-- --> this.securityFilterChainBuilders.add(securityFilterChainBuilder); return this; } // After execution is complete, in WebSecurity, // List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders, length = 1;
Then enter configure() in duBuild;
configure()
private void configure() throws Exception {<!-- --> Collection<SecurityConfigurer<O, B>> configurers = getConfigurers(); // The length of configurers is 1, which is the previous custom configuration class object: SpringSecurityTest object for (SecurityConfigurer<O, B> configurer : configurers) {<!-- --> configurer. configure((B) this); } } // will enter the custom configuration class @Override public void configure(WebSecurity web) throws Exception {<!-- --> super. configure(web); }
After the execution is complete, execute performBuild();
performBuild()
Here securityFilterChainBuilders length = 1, which is added in the previous init() method. Then enter the build() method
@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"); }
Enter the doBuild method again, and also execute the init(), configure(), and performBuild methods
Secondary doBuild
Secondary init
This time, when entering init and obtaining the configuration, 12 configurations were obtained, all of which are built in spring security.
// 0, 1, 3, 6, 10 // ExceptionHandlingConfigurer, HeadersConfigurer, SecurityConfigurerAdapter's init did not operate
Take a screenshot of some configuration initialization content, you can skip it first:
logoutConfigure, init content:
After addMapping, there is one more content
Remember Me:
Secondary configure()
12 configuration objects are also traversed during configure
Screenshot part configure content:
Secondary performBuild()
After the previous configure, there are 12 elements in the filters at this time, and they need to be added to the DefaultSecurityFilterChain object.
Finally, the DefaultSecurityFilterChain object is returned, and it is also returned as a result in doBuild, and returns all the time, returning to the first performBuild
Return to the first performBuild
// part of performBuild(): for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {<!-- --> // Add the DefaultSecurityFilterChain object returned earlier to securityFilterChains (a list object) securityFilterChains.add(securityFilterChainBuilder.build()); } // Proxy securityFilterChains (length 1) to generate proxy object filterChainProxy FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains); ... Filter result = filterChainProxy; if (this.debugEnabled) {<!-- --> this.logger.warn("\ \ " + "************************************ ***********************************\ " + "********** Security debugging is enabled. ***************\ " + "********** This may include sensitive information. ***************\ " + "********** Do not use in a production system! ***************\ " + "************************************************ *********************\ \ "); result = new DebugFilter(filterChainProxy); } // See below for details this.postBuildAction.run(); // Finally return filterChainProxy return result;
// this.postBuildAction.run(); // When the WebSecurityConfigurerAdapter called the init method earlier: @Override public void init(WebSecurity web) throws Exception {<!-- --> HttpSecurity http = getHttp(); // There is a postBuildAction method here, web.addSecurityFilterChainBuilder(http).postBuildAction(() -> {<!-- --> // When this.postBuildAction.run(); is executed, this method will be called: FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class); web.securityInterceptor(securityInterceptor); }); }
So add FilterSecurityInterceptor at the end
The first performBuilder will return FilterChainProxy and return to the springSecurityFilterChain() method return this.webSecurity.build();
The returned object is injected into Spring:
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) // where public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
end
Summary:
? The injected springSecurityFilterChain object is generated by webSecurity.build();
? When building, first read the custom configuration, perform init, configure, and performBuild. During performBuild, it will load the configuration packaged by Springboot, then traverse, execute the init, configure, and performBuild methods respectively, and finally generate the chain from the loaded filters , and then proxy. Inject last.