Spring Security 實戰乾貨:OAuth2登陸獲取Token的核心邏輯

1. 前言

在上一篇Spring Security 實戰乾貨:OAuth2受權回調的核心認證流程中,咱們講了當第三方贊成受權後會調用redirectUri發送回執給咱們的服務器。咱們的服務器拿到一箇中間授信憑據會再次進行認證,目的是爲了獲取Token。而這個邏輯由OAuth2LoginAuthenticationProvider負責,通過上一文的分析後咱們發現獲取Token的具體邏輯由OAuth2AuthorizationCodeAuthenticationProvider來完成,今天就把它的流程搞清楚,來看看Spring Security OAuth2 認證受權獲取Token的具體步驟。java

注意:本 Spring Security乾貨系列教程的OAuth2相關部分是在 Spring Security 5.x版本的。

2. OAuth2AuthorizationCodeAuthenticationProvider

該類是AuthenticationProvider針對OAuth 2.0Authorization Code Grant模式的實現。關於AuthenticationProvider有必要簡單強調一下,它已經屢次在Spring Security乾貨系列中出現,十分重要!必定要去看看相關的分析和使用,它是你根據業務擴展認證方式渠道的重要入口。spring

2.1 OAuth2AccessTokenResponseClient

在該實現中包含了一個OAuth2AccessTokenResponseClient成員變量,它抽象了經過tokenUri端點從認證服務器獲取Token的細節。你能夠根據OAuth 2.0經常使用的四種模式來進行實現它, 以達到根據不一樣的策略來獲取Token的能力。編程

OAuth 2.0 四種模式的對應實現

Spring Security 5OAuth 2.0登陸的配置中默認使用DefaultAuthorizationCodeTokenResponseClient。若是你想使用自定義實現的話能夠經過HttpSecurity來配置:服務器

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.oauth2Login()
                    .tokenEndpoint()
                // 注入自定義的 OAuth2AccessTokenResponseClient
                    .accessTokenResponseClient(authorizationCodeTokenResponseClient);
            // 其它省略

        }

接下來咱們看看DefaultAuthorizationCodeTokenResponseClient實現的獲取Token的邏輯:ide

@Override
public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) {
   Assert.notNull(authorizationCodeGrantRequest, "authorizationCodeGrantRequest cannot be null");
// 1. 封裝調用tokenUri所須要的請求參數RequestEntity
   RequestEntity<?> request = this.requestEntityConverter.convert(authorizationCodeGrantRequest);

   ResponseEntity<OAuth2AccessTokenResponse> response;
   try {
   // 2. 經過RestTemplate 發起請求獲取 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. 解析 ResponseEntity 組織返回值 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;
}

這裏的方式跟我另外一個開源項目Payment Spring Boot的請求方式殊途同歸,都是三個步驟:學習

  1. 組織參數RequestEntity
  2. RestOperations發起請求。
  3. 解析ResponseEntity組織返回值。

若是有些的OAuth 2.0認證服務器獲取Token的方式比較特殊你能夠自行實現OAuth2AccessTokenResponseClientui

3. 總結

OAuth2AccessTokenResponseClientOAuth2AuthorizationCodeAuthenticationProvider的核心要點。搞清楚它的做用和機制就能夠了。這裏咱們總結一下OAuth2AuthorizationCodeAuthenticationProvider的認證過程:this

  1. 檢測未授信OAuth2AuthorizationCodeAuthenticationToken的狀態是否合法。
  2. 經過OAuth2AccessTokenResponseClient請求OAuth 2.0認證服務器獲取Token等信息。
  3. 組裝認證過的授信OAuth2AuthorizationCodeAuthenticationToken返回。

到此OAuth 2.0的登陸流程就搞清楚了,讀者可經過系列文章進行學習批判。我是:碼農小胖哥,多多關注,獲取實用的編程乾貨。spa

關注公衆號:Felordcn 獲取更多資訊rest

我的博客:https://felord.cn

相關文章
相關標籤/搜索