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

相关文章
相关标签/搜索