理解OAuth 2.0受權

1、什麼是OAuth html

2、什麼場景下會用到OAuth受權
json

3、OAuth 2.0中的4個成員
瀏覽器

4、OAuth 2.0受權流程
安全

5、OAuth 2.0受權模式
服務器

一、    authorization code(受權碼模式)
微信

二、    implicit(簡化模式)
app

三、    resource owner password credentials(密碼模式)
ide

四、    client credentials(客戶端模式)
學習

6、小結
優化

 

1、什麼是OAuth

  所謂的OAuth(Open Authorization)本質上就是一張開放的協議,OAuth協議爲用戶資源的受權提供了一個安全的、開放而又簡易的標準。 與以往的受權方式不一樣該受權不會使第三方觸及到用戶的帳戶信息,即第三方無需使用用戶名密碼就能夠申請該用戶資源的受權,所以OAuth是安全的。這是來自百度百科對OAuth的解釋。

  而OAuth2.0呢,故名思義就是OAuth的下一個版本,同時它也是受權領域的行業標準協議,OAuth2.0不支持向後兼容,即不支持OAuth1.0,完全廢止了OAuth1.0協議,OAuth2.0致力於使客戶端開發者經過更簡單的流程爲Web應用、桌面應用以及手機客戶端等設備進行受權。2012年10月,OAuth2.0協議正式發佈爲RFC6749。目前各大開放平臺,如騰訊、新浪、百度等等也都是以OAuth2.0協議做爲支撐。

2、什麼場景下會用到OAuth受權

     目前咱們大多數的應用場景,也是咱們最熟悉的使用環境就是使用第三方登陸,如:微博,QQ,微信,豆瓣等社交平臺登陸,互聯網發展到今天,咱們也都習慣了這種登陸方式,最大的好處就是便捷,簡化了咱們一系列的註冊流程,還有一大堆賬號密碼記不住的困擾,當你碰到一個不支持第三方登陸的網站或者應用的時候,第一感受就是厭惡,一頓噴。人永遠離不開社交,因此經過社交平臺去登陸其餘的平臺,無疑是最受你們歡迎的方式了。  

  就拿CSDN爲例,CSDN是支持第三方平臺登陸的,截圖以下:

若用戶想使用QQ登陸,那麼在傳統的認證模式中,客戶端(CSDN)請求訪問服務器上受限的資源(QQ),須要經過資源全部者(用戶的QQ帳戶)的憑證在服務器上進行認證。爲了支持第三方應用程序(對於QQ來講,CSDN是第三方應用程序,是CSDN去請求訪問QQ的資源)訪問受限資源,資源全部者須要向第三方應用共享其憑證(如用戶QQ的賬號和密碼)。那這樣就會形成如下幾個問題:

  • 第三方應用(CSDN)爲了之後繼續使用,那麼會存儲資源全部者的憑證,如密碼;
  • 服務端須要支持密碼認證,儘管密碼認證不安全;
  • 第三方應用若想訪問資源全部者的其餘資源,資源全部者沒法對其進行限制;
  • 資源全部者沒法收回第三方的訪問權限,除非用戶主動修改密碼;
  • 若是此時第三方的數據泄漏,那也會致使資源全部者其餘數據的泄漏,形成重大損失。

    若此時,CSDN知道了用戶的QQ密碼,那CSDN能夠任意去訪問該用戶的全部信息,而QQ沒法去限制它的訪問,這不論是對QQ仍是用戶自己都會是一件可怕的事,做爲使用者,你永遠都沒法知道應用都幹了些什麼。由此OAuth2.0的出現,就是爲了解決這樣的問題。

3、OAuth 2.0中的4個成員

在OAuth2.0中有4個成員,Resource Owner、Resource Server、Client、Authorization Server,如圖所示:

在上面4個成員中,受權服務器可能與資源服務器在同一臺服務器。

4、OAuth 2.0受權流程

    流程以下,圖片來自RFC6749:

流程解析:

  1. 用戶打開客戶端,客戶端要求向資源全部者(即用戶)給予受權;
  2. 用戶贊成受權;
  3. 客戶端得知用戶贊成受權後,向受權服務器獲取受權;
  4. 受權服務器給予客戶端受權,並將受權碼(Access Token);
  5. 客戶端攜帶受權碼去請求資源服務器;
  6. 資源服務器將受限的資源開放給客戶端。

5、OAuth 2.0受權模式

    受權許但是表示客戶用來獲取訪問令牌的資源全部者受權的憑證。此規範協議規定了4種受權類型:

  • authorization code(受權碼模式)
  • implicit(簡化模式)
  • resource owner password credentials(密碼模式)
  • client credentials(客戶端模式)

下面詳細說明各類受權模式的具體流程:

  一、authorization code(受權碼模式)

受權代碼受權類型用於獲取訪問令牌和刷新令牌,並針對機密客戶端進行優化。它是一個基於重定向的流程,所以客戶端必須可以與資源全部者的用戶代理(一般是Web瀏覽器)而且可以從受權服務器接收傳入請求(經過重定向)。受權碼模式是功能最完整、流程最嚴密的受權模式,它的特色就是經過客戶端的後臺服務器,與"服務提供商"的受權服務器進行互動。受權流程以下:

流程解析:

  1. 客戶端經過用戶代理,重定向請求受權服務器,所需參數:客戶端標識及重定向URL;
  2. 用戶選擇是否給予客戶端受權;
  3. 受權服務器給予客戶端一個認證受權碼,並跳轉到指定的URI;
  4. 客戶端使用該受權碼,重定向到受權服務器,獲取令牌;
  5. 受權服務器校驗該受權碼以及重定向的URI後,向客戶端發送令牌或者更新令牌。

以上均我的解釋,簡化了RFC6749官方文檔說明,大體意思是同樣的。注意的一點是,在用戶贊成受權後,受權服務器並未直接將令牌發送給客戶端,而是先向客戶端發送了一個受權碼,authorization code,而後再攜帶該受權碼,再一次請求受權服務器,校驗無誤後,再發送令牌(access token),這一步是在後臺自動完成的,這樣也使OAuth受權更加安全。

    在該受權流程中,咱們所需的幾個參數,官方文檔中要求指定的參數以下:

  • response_type 必選項 表示的是要求指定的受權類型,此處必須設置爲:code
  • client_id 必選項 客戶端的惟一標識
  • redirect_uri 可選項 重定向的URI
  • scope 可選項 受權的管道
  • state 建議項 表示客戶端狀態,受權服務器會將該狀態原值返回

看完該流程以及所需的參數後,咱們結合實際狀況,仍是上面提到的例子,以CSDN使用QQ登陸爲例,看一下該過程:

(A步驟)點擊QQ登陸,跳轉到QQ賬號安全登陸界面,即騰訊的互聯平臺,咱們能夠直接拿到此時CSDN要請求的地址:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&

response_type=code&

client_id=100270989&

redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&

state=test

這樣咱們能夠很清楚的看到在上面的URL中,發起了一個get請求,他的受權類型爲code 受權碼模式,以及client_id,redirect_uri,state等信息,而此時頁面也跳轉到了用戶代理的頁面,讓用戶去決定是否要贊成受權 :

(C步驟)當用戶輸入用戶名密碼後點擊受權並登陸,服務器會先驗證你輸入的是否正確,若是正確,頁面就會跳轉到redirect_uri的地址中,而在這個過程當中發生的變化是這樣的,咱們繼續查看這時的URL地址:

https://passport.csdn.net/account/login?oauth_provider=QQProvider&

code=D185F3ED93E4F1B3C5F557E6112C7A9B&

state=test

(D步驟)咱們能夠看到受權並登陸後它重定向到了咱們指定的地址,並且還給予了一個code受權碼,另外state狀態仍是在請求登陸時的狀態,在下一個步驟中,是客戶端向受權服務器申請令牌,包含如下參數:

  • grant_type 表示受權模式,此處固定爲authorization_code,必選
  • code 表示上一步獲取到的受權碼,必選
  • redirect_uri 表示重定向URI,必選
  • client_id 表示客戶端ID,必選

在使用騰訊開放平臺時,它會要求有一個client_secrect,是對應你客戶端ID的一個私鑰,它也是在客戶端註冊時產生的,因此在使用QQ登陸獲取令牌時,也必須指定該選項:client_secret,具體的能夠看騰訊的開發文檔。那麼實際上申請令牌的這個過程咱們是看不到的,返回authorization code 後,咱們會看到咱們的客戶端此時已經登陸成功了。例如:

POST /token HTTP/1.1

Host: graph.qq.com/oauth2.0/token

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA

&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&client_secret=fdhsjfdsj32jjfhjdk

(E步驟)若以上返回成功,那麼在E步驟中會返回以下信息:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

 

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",

"example_parameter":"example_value"

}

裏面包含了咱們所須要的令牌access token以及有效期等信息。實際上在咱們實際應用過程當中,咱們不止是到這裏就結束了,咱們會使用access token令牌再去請求資源服務器,獲取能夠被調用的資源,以及一些其餘的操做。

  二、implicit(簡化模式)

簡化模式用於獲取訪問令牌(但它不支持令牌的刷新),並對運行特定重定向URI的公共客戶端進行優化,而這一些列操做一般會使用腳本語言在瀏覽器中完成,令牌對訪問者是可見的,且客戶端也不須要驗證。具體流程以下:

步驟解析:

  1. 客戶端攜帶客戶端標識以及重定向URI到受權服務器;
  2. 用戶確認是否要受權給客戶端;
  3. 受權服務器獲得許可後,跳轉到指定的重定向地址,並將令牌也包含在了裏面;
  4. 客戶端不攜帶上次獲取到的包含令牌的片斷,去請求資源服務器;
  5. 資源服務器會向瀏覽器返回一個腳本;
  6. 瀏覽器會根據上一步返回的腳本,去提取在C步驟中獲取到的令牌;
  7. 瀏覽器將令牌推送給客戶端。

(A步驟)中須要用到的參數,注意在這裏要使用"application/x-www-form-urlencoded"格式:

  • response_type 必選項,此值必須爲"token"
  • client_id 必選項
  • redirect_uri 可選項
  • scope 可選項
  • state 建議選項

    例如:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz 
 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 
 Host: server.example.com 

    (C步驟)中返回的參數包含:

  • access_token 必選項
  • token_type 必選項
  • expires_in 建議選項
  • scope 可選項
  • state 必選項

    例如:

HTTP/1.1 302 Found 
 Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA 
  三、resource owner password credentials(密碼模式) &state=xyz&token_type=example&expires_in=3600 

密碼模式適合創建在客戶端與資源全部者具備信任關係的狀況下,例如它是一個設備的操做系統或者具備很高權限的應用。這種模式用戶要向客戶端提供本身的用戶名密碼,從而達到向服務提供商索取受權。受權服務器在啓動此類型時,要特別當心,只有在其餘的受權方式不被容許的狀況下才可使用這種受權模式。流程以下:

  1. 客戶端要求使用資源全部者的密碼;
  2. 資源全部者給予用戶名密碼後,客戶端向受權服務器發起申請令牌的請求;
  3. 受權服務器將令牌發放給客戶端。

步驟解析:

(B步驟)所需參數:

  • grant_type 必選項 此值必須爲"password"
  • username 必選項 用戶名
  • password 必選項 密碼
  • scope 可選項

例如:

POST /token HTTP/1.1

Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

    (C步驟)發放令牌:

HTTP/1.1 200 OK 
 Content-Type: application/json;charset=UTF-8 
 Cache-Control: no-store 
 Pragma: no-cache 

 

 { 
 "access_token":"2YotnFZFEjr1zCsicMWpAA", 
 "token_type":"example", 
 "expires_in":3600, 
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", 
 "example_parameter":"example_value" 
  四、client credentials(客戶端模式) }

客戶端模式是4種模式中最簡單的一種模式。客戶端可使用客戶端憑據請求訪問令牌(或者其餘支持的認證方式),在這種模式中,客戶端佔據主導地位,它不須要用戶的贊成,能夠直接向受權服務器索取令牌,嚴格來講,該模式並不存在受權的問題,流程以下:

  1. 客戶端向受權服務器發起請求索要令牌;
  2. 受權服務器將令牌發放給客戶端。

步驟解析:

(A步驟)中所需的參數::

  • grant_type 必選項 此值必須爲client_crendentials
  • scope 可選項

例如:

POST /token HTTP/1.1

Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

(B步驟)受權服務器返回結果:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"example_parameter":"example_value"

}

6、小結

    以以上內容簡要介紹了關於OAuth受權的一些基礎知識以及各類受權模式的具體流程。在後面的文章中,會結合本篇內容,陸續講解如何在.net core中藉助IdentityServer4 使用 OAuth 2.0受權。

掃描二維碼關注個人公衆號,共同窗習,共同進步!

相關文章
相關標籤/搜索