OAuth2.0系列之基本概念和運作流程(一)
阿新 • • 發佈:2020-06-04
@[TOC](OAuth2.0系列之基本概念和運作流程)
## 一、OAuth2.0是什麼?
### 1.1 OAuth2.0簡介
[OAuth 2.0](https://oauth.net/2)是目前最流行的授權機制,用來授權第三方應用
> OAuth是一種開放協議, 允許使用者讓第三方應用以安全且標準的方式獲取該使用者在某一網站,移動或者桌面應用上儲存的祕密的資源(如使用者個人資訊,照片,視訊,聯絡人列表),而無需將使用者名稱和密碼提供給第三方應用。
OAuth 1.0協議(RFC5849)作為一個指導性文件釋出,是一個小社群的工作成果。
本標準化規範在OAuth 1.0的部署經驗之上構建,也包括其他使用案例以及從更廣泛的IETF社群收集到的可擴充套件性需求。
OAuth 2.0協議不向後相容OAuth 1.0。這兩個版本可以在網路上共存,實現者可以選擇同時支援他們。
### 1.2 OAuth2.0官方文件
官網:[https://oauth.net/2/](https://oauth.net/2/) ,官網只有英文版文件,您也可以參考翻譯過來的文件,連結:[OAuth2 RFC6749中文翻譯](https://colobu.com/2017/04/28/oauth2-rfc6749/)
OAuth2.0在安全性方面做了比較大的提高,簡單來說OAuth2.0就是一種授權協議,可以用來授權,隨意點個網站,如圖這種網站,使用者不想註冊,就可以用微信、支付寶登入,就是場景是很常見的,也是OAuth2.0的應用
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020052218191213.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ0MjczOTE=,size_16,color_FFFFFF,t_70)
## 二、OAuth2.0原理
OAuth2.0是一種授權機制,正常情況,不使用OAuth2.0等授權機制的系統,客戶端是可以直接訪問資源伺服器的資源的,為了使用者安全訪問資料,在訪問中間添加了Access Token機制。客戶端需要攜帶Access Token去訪問受到保護的資源。所以OAuth2.0確保了資源不被惡意客戶端訪問,從而提高了系統的安全性。
### 2.1 OAuth2.0流程圖
引用官方圖片介紹OAuth2.0總體流程:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200604134719939.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ0MjczOTE=,size_16,color_FFFFFF,t_70)
* (A)客戶端向從資源所有者請求授權。
* (B)客戶端收到授權許可,資源所有者給客戶端頒發授權許可(比如授權碼code)
* (C)客戶端與授權伺服器進行身份認證並出示授權許可(比如授權碼code)請求訪問令牌。
* (D)授權伺服器驗證客戶端身份並驗證授權許可,若有效則頒發訪問令牌(accept token)。
* (E)客戶端從資源伺服器請求受保護資源並出示訪問令牌(accept token)進行身份驗證。
* (F)資源伺服器驗證訪問令牌(accept token),若有效則滿足該請求。
## 三、 OAuth2.0的角色
OAuth2.0定義如下角色:
>引用[OAuth2 RFC6749中文翻譯](https://colobu.com/2017/04/28/oauth2-rfc6749/):
>* 資源所有者(Resource Owner): 能夠許可受保護資源訪問許可權的實體。當資源所有者是個人時,它作為終端使用者被提及。
>* 使用者代理(User Agent): 指的的資源擁有者授權的一些渠道。一般指的是瀏覽器、APP
>* 客戶端(Client) 使用資源所有者的授權代表資源所有者發起對受保護資源的請求的應用程式。術語“客戶端”並非特指任何特定的的實現特點(例如:應用程式是否在伺服器、桌上型電腦或其他裝置上執行)。
>* 授權伺服器(Authorization Server): 在成功驗證資源所有者且獲得授權後頒發訪問令牌給客戶端的伺服器。
授權伺服器和資源伺服器之間的互動超出了本規範的範圍。授權伺服器可以和資源伺服器是同一臺伺服器,也可以是分離的個體。一個授權伺服器可以頒發被多個資源伺服器接受的訪問令牌。
>* 資源伺服器(Resource Server): 託管受保護資源的伺服器,能夠接收和響應使用訪問令牌對受保護資源的請求。
## 四、OAuth2.0授權模式
OAuth2.0有4種授權模式:
* 授權碼模式(authorization code)
* 簡化模式(implicit)
* 密碼模式(resource owner password credentials)
* 客戶端模式(client credentials)
其中最常用的是授權碼模式,4種授權模式的詳細介紹可以參考阮一峰老師的:[OAuth 2.0 的四種方式](http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html)
### 4.1 授權碼模式(authorization code)
授權碼(authorization code)方式,指的是第三方應用先申請一個授權碼,然後再用該碼獲取令牌。
官網圖片:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200604141509433.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ0MjczOTE=,size_16,color_FFFFFF,t_70)
從調介面方面,簡單來說:
* 第一步:獲取code:
eg:oauthServer+"/oauth/authorize?client_id="+clientId+"&response_type=code&redirect_uri="+redirectUrl+"&scope=all"
如果沒有登入,則會跳轉到統一身份認證登入頁面。如果使用者登入了,呼叫介面後,會重定向到redirect_uri,授權碼會作為它的引數
* 第二步:獲取access_token
eg:oauthServer+"/oauth/token?code="+code+"&grant_type=authorization_code&client_secret="+clientSecret+"&redirect_uri="+redirectUri+"&client_id="+clientId
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODk1MzQ5NzMsInVzZXJfbmFtZSI6Im5pY2t5IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9hZG1pbiJdLCJqdGkiOiJmMjM0M2Q0NC1hODViLTQyOGYtOWE1ZS1iNTE4NTAwNTM5ODgiLCJjbGllbnRfaWQiOiJvYSIsInNjb3BlIjpbImFsbCJdfQ.LWkN2gC2dBrGTn5uSPzfdW6yRj7jhlX87EE8scY02hI",
"token_type": "bearer",
"expires_in": 59,
"scope": "all",
"user_name": "nicky",
"jti": "f2343d44-a85b-428f-9a5e-b51850053988"
}
```
* 第三步:訪問系統資源,此時統一認證服務會根據該認證客戶端許可權資訊判斷,決定是否返回資訊。
訪問:http://localhost:8084/api/userinfo?access_token=${accept_token}
### 4.2 簡化模式(implicit grant type)
簡化模式(implicit grant type)不通過第三方應用程式的伺服器,直接在瀏覽器中向認證伺服器申請令牌,跳過了"授權碼"這個步驟,因此稱簡化模式
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200604142316843.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ0MjczOTE=,size_16,color_FFFFFF,t_70)
從調介面方面,簡單來說:
* 第一步:訪問授權,要傳client_id:客戶端id,redirect_uri:重定向uri,response_type為token,scope是授權範圍,state是其它自定義引數
http://localhost:8888/oauth/authorize?client_id=cms&redirect_uri=http://localhost:8084/callback&response_type=token&scope=read&state=123
* 第二步:授權通過,會重定向到redirect_uri,access_token碼會作為它的引數
http://localhost:8084/callback#access_token=${accept_token}&token_type=bearer&state=123&expires_in=120
* 第三步:拿到acceptToken之後,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
### 4.3 密碼模式(resource owner password credentials)
密碼模式中,使用者向客戶端提供自己的使用者名稱和密碼,這通常用在使用者對客戶端高度信任的情況
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200604150959346.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ0MjczOTE=,size_16,color_FFFFFF,t_70)
從調介面方面,簡單來說:
* 第一步:直接傳username,password獲取token
http://localhost:8888/oauth/token?client_id=cms&client_secret=secret&username=admin&password=123456&grant_type=password&scope=all
* 第二步:拿到acceptToken之後,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
### 4.4 客戶端模式(client credentials)
客戶端模式(client credentials)適用於沒有前端的命令列應用,即在命令列下請求令牌
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200604151018785.png)
從調介面方面,簡單來說:
* 第一步: 獲取token
http://localhost:8888/oauth/token?client_id=cms&client_secret=123&grant_type=client_credentials&scope=all
* 第二步:拿到acceptToken之後,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
學習必要的理論知識後,還是實踐一下才能明白整個流程,詳情參考我OAuth2.0系列部落格專欄:[OAuth2.0系列部落格](https://blog.csdn.net/u014427391/category_10033528.html),SpringBoot的參考我係列部落格專欄:[SpringBoot系列部落格](https://blog.csdn.net/u014427391/category_9195353.html)
## 五、優質參考資料
* [OAuth 2.0 的四種方式](http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html#support)
* [OAuth2.0系列部落格專欄](https://blog.csdn.net/anumbrella/category_9302813.html)
* [OAuth2.0 JWT 認證授權](https://www.jianshu.com/p/ca4cebefd1cc)
* [RFC6749官方參考文件](https://tools.ietf.org/html/rfc6749)