在上一篇Spring Security 實戰乾貨:OAuth2受權回調的核心認證流程中,咱們講了當第三方贊成受權後會調用redirectUri
發送回執給咱們的服務器。咱們的服務器拿到一箇中間授信憑據會再次進行認證,目的是爲了獲取Token。而這個邏輯由OAuth2LoginAuthenticationProvider
負責,通過上一文的分析後咱們發現獲取Token的具體邏輯由OAuth2AuthorizationCodeAuthenticationProvider
來完成,今天就把它的流程搞清楚,來看看Spring Security OAuth2 認證受權獲取Token的具體步驟。java
注意:本 Spring Security乾貨系列教程的OAuth2相關部分是在 Spring Security 5.x版本的。
該類是AuthenticationProvider
針對OAuth 2.0中Authorization Code Grant模式的實現。關於AuthenticationProvider
有必要簡單強調一下,它已經屢次在Spring Security乾貨系列中出現,十分重要!必定要去看看相關的分析和使用,它是你根據業務擴展認證方式渠道的重要入口。spring
在該實現中包含了一個OAuth2AccessTokenResponseClient
成員變量,它抽象了經過tokenUri
端點從認證服務器獲取Token的細節。你能夠根據OAuth 2.0經常使用的四種模式來進行實現它, 以達到根據不一樣的策略來獲取Token的能力。編程
在Spring Security 5中OAuth 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的請求方式殊途同歸,都是三個步驟:學習
RequestEntity
。RestOperations
發起請求。ResponseEntity
組織返回值。若是有些的OAuth 2.0認證服務器獲取Token的方式比較特殊你能夠自行實現OAuth2AccessTokenResponseClient
。ui
OAuth2AccessTokenResponseClient
是OAuth2AuthorizationCodeAuthenticationProvider
的核心要點。搞清楚它的做用和機制就能夠了。這裏咱們總結一下OAuth2AuthorizationCodeAuthenticationProvider
的認證過程:this
OAuth2AuthorizationCodeAuthenticationToken
的狀態是否合法。OAuth2AccessTokenResponseClient
請求OAuth 2.0認證服務器獲取Token等信息。OAuth2AuthorizationCodeAuthenticationToken
返回。到此OAuth 2.0的登陸流程就搞清楚了,讀者可經過系列文章進行學習批判。我是:碼農小胖哥,多多關注,獲取實用的編程乾貨。spa
關注公衆號:Felordcn 獲取更多資訊
rest