Spring Security combat dry goods: the core logic of OAuth2 login to obtain Token

1. Preface

In the previous article Spring Security combat dry goods: the core authentication process of OAuth2 authorization callback In, we talked about that when the third party agrees to authorize, it will call redirectUri to send a receipt to our server. When our server gets an intermediate credit certificate, it will authenticate again in order to obtain the Token. The OAuth2LoginAuthenticationProvider is responsible for this logic Last article After the analysis, we found that the specific logic of obtaining the Token is completed by oauth2authorizationcodeauthentication provider. Let's clarify its process today and take a look at the specific steps of Spring Security OAuth2 authentication authorization to obtain the Token.

Note: the OAuth2 related part of this Spring Security dry goods series tutorial is in Spring Security 5 Version X.

2. OAuth2AuthorizationCodeAuthenticationProvider

This class is the implementation of AuthenticationProvider for Authorization Code Grant mode in OAuth 2.0. It is necessary to briefly emphasize the AuthenticationProvider, which has been used for many times Spring Security dry goods series Appear, very important! Be sure to look at the relevant analysis and use. It is an important entrance for you to expand the authentication channel according to the business.

2.1 OAuth2AccessTokenResponseClient

This implementation includes an OAuth2AccessTokenResponseClient member variable, which abstracts the details of obtaining tokens from the authentication server through the tokenUri endpoint. You can implement OAuth 2.0 according to the four commonly used modes to achieve the ability to obtain tokens according to different strategies.

In the configuration of OAuth 2.0 login in Spring Security 5, defaultauthorizationcodetoken responseclient is used by default. If you want to use a custom implementation, you can configure it through HttpSecurity:

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.oauth2Login()
                    .tokenEndpoint()
                // Inject custom OAuth2AccessTokenResponseClient
                    .accessTokenResponseClient(authorizationCodeTokenResponseClient);
            // Other omissions

        }

Next, let's look at the logic of obtaining Token implemented by defaultauthorizationcodetoken responseclient:

@Override
public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) {
   Assert.notNull(authorizationCodeGrantRequest, "authorizationCodeGrantRequest cannot be null");
// 1. Encapsulate the request parameter RequestEntity required for calling tokenUri
   RequestEntity<?> request = this.requestEntityConverter.convert(authorizationCodeGrantRequest);

   ResponseEntity<OAuth2AccessTokenResponse> response;
   try {
   // 2. Initiate a request through RestTemplate to obtain OAuth2AccessTokenResponse
      response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class);
   } catch (RestClientException ex) {
      OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,
            "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null);
      throw new OAuth2AuthorizationException(oauth2Error, ex);
   }

  // 3. resolve the ResponseEntity organization return value OAuth2AccessTokenResponse
   OAuth2AccessTokenResponse tokenResponse = response.getBody();

   if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) {
  
      // originally requested by the client in the Token Request
      tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse)
            .scopes(authorizationCodeGrantRequest.getClientRegistration().getScopes())
            .build();
   }

   return tokenResponse;
}

The way here is similar to another open source project Payment Spring Boot There are three steps to the request:

  1. Organization parameter RequestEntity.
  2. RestOperations initiates the request.
  3. Resolve the return value of ResponseEntity organization.

If some OAuth 2.0 authentication servers obtain tokens in a special way, you can implement OAuth2AccessTokenResponseClient by yourself.

3. Summary

OAuth2AccessTokenResponseClient is the core of oauth2authorizationcodeauthentication provider. Just find out its function and mechanism. Here we summarize the authentication process of OAuth2AuthorizationCodeAuthenticationProvider:

  1. Check whether the status of OAuth2AuthorizationCodeAuthenticationToken is legal.
  2. Request OAuth 2.0 authentication server to obtain Token and other information through OAuth2AccessTokenResponseClient.
  3. The OAuth2AuthorizationCodeAuthenticationToken that has been assembled and authenticated is returned.

At this point, the login process of OAuth 2.0 is clear. Readers can learn and criticize through a series of articles. I am: little fat brother of code farmer. Pay more attention and get practical programming dry goods.

Pay attention to the official account: Felordcn for more information

Personal blog: https://felord.cn

Tags: Java Spring Boot Spring Security oauth

Posted by evilmonkey on Sat, 16 Apr 2022 23:11:28 +0930