Spring Security 實戰乾貨:客戶端OAuth2授權請求的入口
阿新 • • 發佈:2020-11-10
![](https://img2020.cnblogs.com/other/1739473/202011/1739473-20201110085804324-1005707290.png)
## 1. 前言
在[Spring Security 實戰乾貨:OAuth2第三方授權初體驗](https://mp.weixin.qq.com/s/8EbQ_AugQY19FQ-0t4qaqQ)一文中我先對OAuth2.0涉及的一些常用概念進行介紹,然後直接通過一個DEMO來讓大家切身感受了OAuth2.0第三方授權功能。今天我們來一步一步分析這其中的機制。
## 2. 抓住源頭
> http://localhost:8082/oauth2/authorization/gitee
上面這個請求URL是我們在[上一篇](https://mp.weixin.qq.com/s/8EbQ_AugQY19FQ-0t4qaqQ)文章中提到的客戶端進行第三方認證操作的起點,預設格式為`{baseUrl}/oauth2/authorization/{clientRegistrationId}`,其中`clientRegistrationId`代表著一個第三方標識,可以是微信、支付寶等開放平臺,這裡為`gitee`。使用者點選了這個請求後就開始了授權之旅。假如大家都是從零開始的小白,肯定是要從這個入口來一步一步探尋其中的機制的。Spring Security一定是攔截到了`/oauth2/authorization`後才啟用了OAuth2相關的處理邏輯。那就去抓住這個源頭!從原始碼中搜索嘛!IDEA 快捷鍵`CTRL SHIFT R` 就可以全域性搜尋結果了。
![IDEA 搜尋結果](https://img2020.cnblogs.com/other/1739473/202011/1739473-20201110085804576-1110462105.png)
不出所料找到了三個地方,記下來一個一個看!
### OAuth2AuthorizationRequestRedirectWebFilter
先來看第一個`OAuth2AuthorizationRequestRedirectWebFilter`,它實現了Spring Webflux的`WebFilter`介面,這顯然是Webflux的東西,如果你用到Webflux的話這個會有用,但是不是現在我們用的。
### DefaultOAuth2AuthorizationRequestResolver
第二個是幹嘛的呢,從名稱上看著是一個預設OAuth2授權請求解析器。有時候名稱起的好就知道這個東西大致上幹嘛的,不得不說優秀框架細節抓的很好。它實現了介面`OAuth2AuthorizationRequestResolver`:
```java
public interface OAuth2AuthorizationRequestResolver {
/**
* 從HttpServletRequest物件中解析封裝 OAuth2AuthorizationRequest
*/
OAuth2AuthorizationRequest resolve(HttpServletRequest request);
/**
* 從HttpServletRequest物件以及clientRegistrationId中解析封裝 OAuth2AuthorizationRequest
*/
OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId);
}
```
也就是說當我們請求`/oauth2/authorization`時,`DefaultOAuth2AuthorizationRequestResolver` 會從`/oauth2/authorization`對應的`HttpServletRequest`中提取資料封裝到`OAuth2AuthorizationRequest`請求物件中做進一步使用。
> **注意**:`/oauth2/authorization`這個預設攔截標識也是可以自定義的。
#### OAuth2AuthorizationRequest
這裡簡單提一下`OAuth2AuthorizationRequest` 封裝了我們上一文所描述的一些OAuth2相關概念引數,後續這個請求類我們會用到它。
```java
public final class OAuth2AuthorizationRequest implements Serializable {
private static final long serialVersionUID = 520L;
private String authorizationUri;
private AuthorizationGrantType authorizationGrantType;
private OAuth2AuthorizationResponseType responseType;
private String clientId;
private String redirectUri;
pri