1. Preface

The previous post focused on how to initialize the OAuth2AuthorizationRequest authorization request object when a user initiates a third-party authorization request and how to forward it through the filter to the third party. Today we will follow this process down to see what the server does when it receives an authorization request.

2. OAuth2 Login Authentication

When the third party receives an OAuth2 authorization request, it will pass the authorization acknowledgement to us via a callback request redirect_uri provided by us. Since by default the callback path satisfies /login/oauth2/code/*, we just need to find the filter that intercepts the callback to know how Spring Security handles callbacks. A search confirms that OAuth2LoginAuthenticationFilter is the filter that handles callbacks.

OAuth2LoginAuthenticationFilter

The third-party authentication server appends code and state parameters to the call to redirect_uri, and after being intercepted by this Filter, creates a pending authentication credential OAuth2LoginAuthenticationToken, which is delegated to the AuthenticationManager for authentication.

Once successfully authenticated, the authentication credentials OAuth2AuthenticationToken and the authentication client object OAuth2AuthorizedClient are generated. Finally, OAuth2AuthenticationToken is returned and finally stored in SecurityContextRepository to complete the authentication process; and OAuth2AuthorizedClient is stored in OAuth2AuthorizedClientRepository . The flowchart is as follows.

OAuth2LoginAuthenticationFilter

3. AuthenticationManager

When Spring Security intercepts the callback interface, it encapsulates an OAuth2LoginAuthenticationToken and hands it to the AuthenticationManager for authentication.

The login credentials are encapsulated as UsernamePasswordAuthenticationToken and then the corresponding AuthenticationProvider is found for authentication based on the type of the Token.

AuthenticationManager

4. OAuth2 Corresponding AuthenticationProvider

Then OAuth2 login has a similarity, we need to find the AuthenticationProvider corresponding to the OAuth2LoginAuthenticationToken. Here we find two.

  • OAuth2LoginAuthenticationProvider
  • OidcAuthorizationCodeAuthenticationProvider.

What are the scenarios for each of these two, there is the following fragment in OAuth2LoginAuthenticationToken.

1
2
3
4
5
6
if (loginAuthenticationToken.getAuthorizationExchange()
   .getAuthorizationRequest().getScopes().contains("openid")) {
   // This is an OpenID Connect Authentication Request so return null
   // and let OidcAuthorizationCodeAuthenticationProvider handle it instead
   return null;
}

It means that scopes that contain openid will return null directly and will not be processed by OAuth2LoginAuthenticationToken, while the opposite is true for OidcAuthorizationCodeAuthenticationProvider. In the vein of previous articles OAuth2LoginAuthenticationProvider is what we need.

Interested in learning about OAuth2 authentication based on OIDC.

5. OAuth2LoginAuthenticationProvider

OAuth2LoginAuthenticationProvider implements the authentication process for authorization callbacks.

OAuth2LoginAuthenticationProvider

From the above diagram we can see that the specific authentication is handled by OAuth2AuthorizationCodeAuthenticationProvider, which will get the user’s information and encapsulate it as OAuth2User after the authentication is passed, and finally generate the OAuth2LoginAuthenticationToken for successful authorization.

For space reasons, we will analyze the processing mechanism of OAuth2AuthorizationCodeAuthenticationProvider in the next article.

Reference https://felord.cn/oauth2-login-authentication-filter.html