授權協議——簡單介紹OAuth2幾種授權模式流程

OAuth2

OAuth2是什麼

OAuth(Open Authorization,開放授權)是爲用戶資源的授權定義了一個安全、開放及簡單的標準,第三方無需知道用戶的賬號及密碼,就可獲取到用戶的授權信息
OAuth2.0是OAuth協議的延續版本,但不向後兼容OAuth 1.0即完全廢止了OAuth1.0

Oatuh2用來做什麼

有這樣一種場景,一個用戶(假設是QQ),希望讓一個第三方的應用(比如說某個論壇),能夠得到關於自身的一些信息(唯一用戶標識,比如說QQ號,用戶個人信息,比如說是一些基礎資料,暱稱和頭像等)。但是在獲得這些資料的同時,卻也不能提供用戶名和密碼之類的驗證信息。比如說用戶不可能將自身的用戶名和密碼給第三方讓第三方到用戶中心之類的地方去獲取信息。要達到這樣的結果肯定有許多的實現方式。而Oatuh2就是實現上述目標的一種規範,或者說是具體實現的指導方案。

Oauth2具體做法

OAuth定義了四個角色:

  • 資源所有者(resource owner): 能夠對受保護資源授予訪問權限的實體。當資源所有者是一個人時,它被稱爲終端用戶。
  • 資源服務器(resource server): 託管受保護資源的服務器,能夠接受和響應通過令牌對受保護的資源的請求。
  • 客戶端(client): 代表資源所有者及其授權進行受保護資源請求的應用程序。術語“客戶端”並不暗示任何特定的實現特徵(例如,應用程序是在服務器,臺式機還是其他設備上執行)。
  • 授權服務器(authorization server): 成功後,服務器向客戶端發出訪問令牌驗證資源所有者並獲得授權。

授權服務器和資源服務器之間的交互超出了本規範的範圍。授權服務器可以是與資源服務器相同的服務器或單獨的實體。單個授權服務器可以發出可以被多個資源服務器接受的訪問令牌。

Oauth2的流程

Oauth2,根據RFC6749文檔,大致的流程如下圖所示

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kJaxUlJA-1591176958065)(https://pic4.zhimg.com/80/v2-ba94a5f1e17b74e8cb8176620997ac27_720w.jpg)]

上圖中的client就是第三方應用。可以看到,Oauth的大致思路是一個線性的流程。

  1. 第三方應用向資源持有者請求獲取資源
  2. 資源持有者授權給予第三方應用一個許可
  3. 第三方應用將該許可給予認證服務器進行認證,如果認證成功,返回一個Access Token
  4. 第三方應用使用該access token到資源服務器處獲取該access token對應的資源(也就是第一步中資源持有者自身的資源)

在上面的這個流程中,其中第二步,資源持有者如何授權給予第三方應用一個許可就是最爲關鍵的地方。其中RFC6749文檔給出4種第三方取得授權許可的方式。

  1. 授權碼模式
  2. 簡化模式
  3. 密碼模式
  4. 客戶端模式

其中授權碼模式是步驟流程最爲詳細嚴謹的一種模式。而網絡上大部分的第三方Oauth2實現都是基於授權碼模式的。本文也是主要講解授權碼模式中的相關流程性問題。至於其他的三種模式,讀者可以自行參看RFC6749文檔。

授權碼模式

授權碼模式的流程如下圖所示

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1F9Q1WwK-1591176958067)(https://pic1.zhimg.com/80/v2-768433603a559746ca71a20a6807c9c4_720w.jpg)]

下面來分別講解其中的幾個點

第三方引導用戶跳轉至認證服務器的授權頁面

在引導跳轉的時候需要攜帶如下的幾個參數

  1. response_type:授權類型。授權碼模式下,就固定爲code
  2. app_id:第三方應用的標識id。
  3. redirect_uri:重定向uri,也就是在授權成功後認證服務器讓用戶重定向的地址。一般而言也就是當前用戶在第三方應用中最初的請求地址
  4. scope:授權範圍。可選內容,可以根據第三方應用和實現方的要求自行制定合適的值。
  5. state:透明的驗證參數。RFC6749文檔推薦認證服務器在重定向的時候應該原封不同的返還這個參數。注意,該參數嚴格來說應該是一個必須參數。用來防止CSRF攻擊。也就是說用於讓第三方服務器驗證重定向回來的uri的確是認證服務器的行爲而不是其他的攻擊者僞造的。一般來說跳轉到認證服務器的授權頁面是走的https,但是認證服務器重定向到回調地址的時候可能走的就是http。此時code存在泄漏以及url存在被僞造的風險。那麼第三方應用必須要有辦法驗證該回調是否的確由認證服務器發起,並且的確是之前自己的授權請求導致的回調。做法其實也不復雜,就是在session中保存一個隨機值,作爲state參數。認證服務器回調的時候帶上該state參數,第三方應用驗證該參數是否與自己session中的state參數值一致即可。如果認證的授權頁面不是https加密的,那麼在發出請求的時候,認證state參數可能會被竊取。那麼這個時候還有另外一種做法。也就是第三方應用發送的是加密後的state參數,而認證服務器重定向的時候攜帶的是解密後的state參數。第三方應用只要在session中判斷解密後的值是否與session的一致,也可以達到防止攻擊的目的。這樣,授權頁面也就是可以走在普通的http之中了。

用戶選擇是否給予授權

這一步是一個用戶行爲。目前基本的做法都是讓用戶在授權頁面上輸入用戶名和密碼。爲了保證安全性,這個頁面需要由https來進行保護。當然,如果有其他的方式來保證用戶名密碼,以及認證的state參數不會泄露也是可以的。如果用戶輸入正確的用戶名和密碼,一般就確認爲用戶給予授權。

認證服務器生成code並且讓用戶重定向至指定的url

如果用戶給予授權,則認證服務器需要生成一個唯一的授權碼code。該code的時效性應該比較短,在5分鐘以內比較合適。並且該code只能使用一次,下次就會失效。同時,該code與客戶端的id,redirect-uri參數是一一對應的關係。認證服務器此時應該讓用戶重定向至一開始指定的redirect_uri。攜帶上state和code參數

第三方應用使用code到認證服務器處兌換令牌access token

第三方應用在驗證過state參數的正確性後,接着就可以使用code到認證服務器處換取token。這一步,第三方應用需要攜帶上的參數有

  1. code:就是認證服務器給予的code參數
  2. appid:客戶端的唯一標識
  3. redirect_uri:也就是第一步請求中的重定向參數。因爲code實際上是與appid和redirect_uri一一對應的。所以用code換取令牌的時候也要攜帶上這兩個參數
  4. grant_type: 授權模式,這裏固定爲"authorization_code"
  5. appkey:用於驗證應用的身份。appid和appkey可以理解爲應用自己的用戶名和密碼。

oauth2的服務器本身都是走https。所以都可以直接明文傳輸不需要考慮安全性問題。不過如果不是http的,也可以直接參數用戶名密碼登錄的方式,就是給appkey進行md5運算。 關於爲何不直接傳遞accesstoken的問題,是基於安全考慮。因爲認證服務器是基於Https,而第三方應用可以是http的。如果在回調的時候直接帶上accesstoken,就存在着泄露的問題。

認證服務器返回accesstoken

認證服務器在驗證過參數的合法性後,生成一個全局唯一的token,並且返回給第三方應用。返回的內容採用json表示,返回的參數主要有

  1. access_token: 用於獲取對應資源的令牌
  2. expires_time: 該令牌的有效期
  3. reflesh_token: 用戶獲取新的accesstoekn的token。由於accesstoken的有效期比較短,一旦失效,用戶需要再走上面的流程是比較繁瑣的。爲了提升用戶體驗,可以使用reflesh_token來獲取新的accesstoken。不過這個做法,已經有不同的實現方將這個返回參數去掉了。因爲實際上reflesh_token也就意味着accesstoekn是永久有效的了。那和直接延長accesstoken的有效期也沒有直接區別了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章