1. Introduction

We work on a paper introduces UsernamePasswordAuthenticationFilter process, leaving behind a small stage, as a Servlet Filter there should be a doFilter method, and it doesn’t, In fact it is the parent of the AbstractAuthenticationProcessingFilter provides a concrete implementation. Later we will use this implementation to introduce today’s protagonist, AuthenticationManager, to continue the user authentication process.

2. AbstractAuthenticationProcessingFilter

Let’s take a look at AbstractAuthenticationProcessingFilter core doFilter method implementation:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {

   HttpServletRequest request = (HttpServletRequest) req;
   HttpServletResponse response = (HttpServletResponse) res;

    // Determine whether authentication is required by the request URI, such as the default /login
   if(! requiresAuthentication(request, response)) { chain.doFilter(request, response);return;
   }

   if (logger.isDebugEnabled()) {
      logger.debug("Request is to process authentication");
   }

   Authentication authResult;

   try {
       AttemptAuthentication executes the subclass hook method attemptAuthentication to obtain the result object attemptAuthentication, which cannot be empty or is returned
      authResult = attemptAuthentication(request, response);
      if (authResult == null) {
         // return immediately as subclass has indicated that it hasn't completed
         // authentication
         return;
      }
       // Process session policy, where there is no policy by default
      sessionStrategy.onAuthentication(authResult, request, response);
   }
   catch (InternalAuthenticationServiceException failed) {
      logger.error(
            "An internal error occurred while trying to authenticate the user.",
            failed);
       / / if there are any abnormal will be handed over to authentication failed processor AuthenticationFailureHandler to deal with
      unsuccessfulAuthentication(request, response, failed);

      return;
   }
   catch (AuthenticationException failed) {
      // Authentication failed
      unsuccessfulAuthentication(request, response, failed);

      return;
   }

   / / to other filter chain after a successful authentication And finally to the authentication processor AuthenticationSuccessHandler treatment success
   if (continueChainBeforeSuccessfulAuthentication) {
      chain.doFilter(request, response);
   }

   successfulAuthentication(request, response, chain, authResult);
}
Copy the code

Most of the logic is clear here, but the key lies in the attemptAuthentication method, which we already analyzed in the previous article is the authenticate method of AuthenticationManager to process the authentication logic. Next, we’ll focus on this interface to help us understand the Spring Seucirty authentication process.

3. AuthenticationManager

The AuthenticationManager interface method is very peculiar, with both the input parameter and the return value being of type Authentication. The function of this interface is to authenticate the user’s untrusted credential. If the credential passes the authentication, the credential of the credit status is returned. Otherwise, the AuthenticationException AuthenticationException is thrown.

3.1 Initialization process of AuthenticationManager

So where was the AuthenticationManager configuration of AbstractAuthenticationProcessingFilter? Seen Spring Security void in the dry goods should know WebSecurityConfigurerAdapter series of battle the configure (AuthenticationManagerBuilder Auth is the place to configure AuthenticationManager. I summarized the initialization process of AuthenticationManager according to the source code. I believe you can help you read the relevant source code:

It is important to note that if we use a custom configuration, we must not follow error demonstrations like the following:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(weChatSecurityConfigProperties.getUserDetailsService());
    daoAuthenticationProvider.setPasswordEncoder(multiPasswordEncoder());
    auth.authenticationProvider(daoAuthenticationProvider);
    // Calling super will not take effect, so do not write the following statement
    super.configure(auth);
}
Copy the code

3.2 Authentication process of AuthenticationManager

The implementation of AuthenticationManager, ProviderManager, manages a number of AuthenticationProviders. Each AuthenticationProvider supports only a specific type of Authentication. If it does not support Authentication, the Authentication provider will be skipped. Another function is to authenticate the adaptive Authentication. As long as one Authentication succeeds, the Authentication is considered successful, and all Authentication fails. After successful Authentication, Authentication becomes a credential and triggers an event of successful Authentication. If the authentication fails, an exception is thrown to trigger an authentication failure event.

From this we can see that the Authentication manager AuthenticationManager provides a specific Authentication function for a specific Authentication. We can use this to realize multiple Authentication coexistence.

4. To summarize

Through this article, we analyze the initialization process and authentication process of Spring Security AuthenticationManager AuthenticationManager. If you are familiar with the logic of AuthenticationManager, you can realize the coexistence of multiple authentication methods and other capabilities. Implement a lot of useful logic, which is important for integrating Spring Security into your project. More attention: code farmer Xiao Pangge to get more original dry goods.

Follow our public id: Felordcn for more information

Personal blog: https://felord.cn