spring-security (twenty) core Filter-SecurityContextPersistenceFilter

1. SecurityContextPersistenceFilter functions and properties
1. When we introduced the spring filter sequence, we briefly introduced SecurityContextPersistenceFilter, which has two main functions.
  • At the beginning of the request, the securityContext is obtained from the corresponding SecurityContextRepository and stored in the SecurityContextHolder
  • At the end of the request, clear the securityContext in the SecurityContextHolder, and store the new SecurityContext in the corresponding SecurityContextRepository after the execution of the request.

It is necessary to clear the SecurityContext in the SecurityContextHolder after the request, because by default the SecurityContextHolder will store the SecurityContext in ThreadLocal, and this thread happens to exist in the thread pool of the servlet container. When the request is assigned to this thread from the thread pool, the program will get the wrong authentication information.
2.SecurityContext storage class SecurityContextRepository
Starting from Spring Security 3.0, both storing and loading securityContext are done through SecurityContextRepository
public interface SecurityContextRepository {
SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);

void saveContext(SecurityContext context, HttpServletRequest request,
                 HttpServletResponse response);
boolean containsContext(HttpServletRequest request);
}

The parameter HttpRequestResponseHolder is just a wrapper class for request and response, which allows the specific implementation class of this interface to wrap the request and response, and the returned object will be passed into the subsequent filter.
By default, the specific implementation class used by spring boot is HttpSessionSecurityContextRepository, and the SecurityContext is stored in the properties of HttpSession. The main configuration property of this class is allowSessionCreation, which is true by default, so that when the session corresponding to the security context needs to be stored for the authenticated user This class will create the session object for the current user when it doesn't exist yet.
There is another implementation of this interface in spring security - NullSecurityContextRepository, this class will not store the current SecurityContext even if the user has been authenticated successfully.
2. In the spring boot environment, how does the filter use the Java config mechanism to be added to the servlet to intercept our requests?
In the previous chapter (spring-security (sixteen) Filter configuration principle) , we know that the spring security-related Filter is to call the build of HttpSecurity in the build method of WebSecurity to build a SecurityFilterChain after sorting the filter list appended to HttpSecurity, then append all SecurityFilterChains to FilterChainProxy, and finally register through DelegatingFilterProxy In the ServletContext, let's mainly see how this class is appended to the filter list of HttpSecuriy.
1. Starting from our configuration entry WebSecurityConfigurerAdapter class, in the getHttp() method of this class, the http.securityContext() method will be called when the default configuration is used
public SecurityContextConfigurer<HttpSecurity> securityContext() throws Exception {
    return getOrApply(new SecurityContextConfigurer<HttpSecurity>());
}

In this method, a configuration class SecurityContextConfigurer that implements the SecurityConfigurer interface is created. By calling the getOrApply method, it is finally added to the configurers property of HttpSecurity. Through this configuration class, we can also set the SecurityContextRepository property in the SecurityContextPersistenceFilter.
2. When WebSecurity builds HttpSecurity, it will call the build method of HttpSecurity. This method will first execute the configure() method of HttpSecurity, which is to call the configure method of each SecurityConfigurer in the configurers property in turn.
private void configure() throws Exception {
  Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
  for (SecurityConfigurer<O, B> configurer : configurers) {
     configurer.configure((B) this);
  }
}

Let's take a look at the configure method of SecurityContextConfigurer
public void configure(H http) throws Exception {
  SecurityContextRepository securityContextRepository = http
     .getSharedObject(SecurityContextRepository.class);
  if(securityContextRepository == null) {
	 securityContextRepository = new HttpSessionSecurityContextRepository();
	}
  SecurityContextPersistenceFilter securityContextFilter = new
  SecurityContextPersistenceFilter(securityContextRepository);
  SessionManagementConfigurer<?> sessionManagement = http
	 .getConfigurer(SessionManagementConfigurer.class);
  SessionCreationPolicy sessionCreationPolicy = sessionManagement == null ? null: sessionManagement.getSessionCreationPolicy();
	if (SessionCreationPolicy.ALWAYS == sessionCreationPolicy) {
		securityContextFilter.setForceEagerSessionCreation(true);
	}
	securityContextFilter = postProcess(securityContextFilter);
	http.addFilter(securityContextFilter);
}

Obviously, a SecurityContextPersistenceFilter will be created in this method, the corresponding SecurityContextRepository property will be set, and it will be added to the HttpSecurity filter list, so that we can filter our requests like other filters.

It can be seen that the filter function is not complicated. In fact, spring security clearly splits the function through a large number of filters, which not only facilitates expansion, but also greatly improves the readability of the code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326079506&siteId=291194637