OAuth2基本概念和運做流程

 

OAuth(開放受權)是一個關於受權的開放標準,容許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。目前的版本是2.0版,本文將對OAuth2.0的一些基本概念和運行流程作一個簡要介紹。主要參考RFC-6749html

應用場景

這裏有兩個典型的例子:git

  • 好比你瀏覽某個網站的技術文章,發現其中某段介紹的不夠詳細,想留言給做者提問,點擊評論,結果發現須要有這個網站的帳號才能留言,此時有兩個選擇,一個是新註冊一個此網站的帳號,二是點擊經過github快速登陸。前者你以爲過於繁瑣,直接點擊了github登陸,此時,OAuth的認證流程就開始了。經過引導跳轉到github界面,會提示你是否受權該網站使用你的github用戶信息,點擊確認,跳轉回原網站,發現已經使用你的github帳號默認註冊了一個用戶,並且還不須要用戶名和密碼,便捷高效。
  • 假若有一個雲沖印的網站,能夠將你存儲在Google的照片沖印出來,用戶爲了使用該服務,必須讓雲沖印讀取Google上的照片。爲了拿到照片,雲沖印必須得拿到一個用戶的受權,如何獲取這個用戶受權呢?傳統方法是用戶將用戶名和密碼告訴雲沖印,那麼雲沖印就能夠自由無限制的訪問了(至關於用戶本身訪問),這樣顯然是不行的,有幾個嚴重的缺點:github

    • 雲沖印爲了保存後續服務,會保存用戶的密碼,這樣很不安全。
    • 雲沖印擁有了獲取用戶存儲在Google的全部資料的權力,用戶無法限制雲沖印獲得的受權範圍和受權有效期。
    • 用戶只有修改密碼,才能收回賦予雲沖印的權力,可是若是還受權給了其餘的應用,那麼密碼的修改將影響到全部被受權應用。
    • 只要有一個第三方應用程序被破解,就會致使用戶密碼泄漏,以及全部被密碼保護的數據泄漏。(例子來自阮一峯-理解OAuth2.0)

能夠看出,OAuth就是爲解決如上例子而誕生的。web

名詞解釋

如下幾個名詞相當重要:瀏覽器

  • Resource Owner:資源全部者。即用戶。
  • Client:客戶端(第三方應用)。如雲沖印。
  • HTTP service:HTTP服務提供商,簡稱服務提供商。如上文提到的github或者Google。
  • User Agent:用戶代理。本文中就是指瀏覽器。
  • Authorization server:受權(認證)服務器。即服務提供商專門用來處理認證的服務器。
  • Resource server:資源服務器,即服務提供商存放用戶生成的資源的服務器。它與認證服務器,能夠是同一臺服務器,也能夠是不一樣的服務器。
  • Access Token:訪問令牌。使用合法的訪問令牌獲取受保護的資源。

運行流程

運行流程

  • (A)客戶端向資源全部者請求受權。受權請求能夠直接對資源全部者(如圖所示)進行,或者經過受權服務器做爲中介進行間接訪問(首選方案)。
  • (B)資源全部者容許受權,並返回憑證(如code)。
  • (C)客戶端經過受權服務器進行身份驗證,並提供受權憑證(如code),請求訪問令牌(access token)。
  • (D)受權服務器對客戶端進行身份驗證,並驗證受權憑證,若是有效,則發出訪問令牌。
  • (E)客戶端向資源服務器請求受保護的資源,並經過提供訪問令牌來進行身份驗證。
  • (F)資源服務器驗證訪問令牌,若是正確則返回受保護資源。

受權

從運行流程不難看出,要獲取access token必須先獲得用戶受權(authorzation grant),那麼若是獲取這麼用戶受權呢?OAuth 2.0定義了四種類型的受權類型:安全

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

受權碼模式(authorization code服務器

受權碼模式是功能最完整、使用最普遍、流程最嚴密的受權模式。框架

因爲這是一個基於重定向的流,因此客戶端必須可以與資源全部者的用戶代理(一般是web瀏覽器)進行交互,而且可以從受權服務器接收傳入的請求(經過重定向)。
受權碼模式網站

  • (A)用戶訪問客戶端,客戶端將用戶導向受權服務器,經過用戶代理(User-Agent)發送包括它的客戶端標識符、請求的範圍、本地狀態和一個重定向URI,受權服務器在授予(或拒絕)訪問權後將其發送給用戶代理。
  • (B)受權服務器對資源全部者進行身份驗證(經過用戶代理),並肯定資源全部者是否授予或拒絕客戶端的訪問請求。
  • (C)假如資源全部者贊成受權請求,那麼受權服務器將會使用前面提供的或者事先指定的重定向URI(redirection URI),重定向到客戶端,並附上一個受權碼(code)和一個前面提供的本地狀態(state)(若是有的話,則會原值返回)。
  • (D)客戶端收到受權碼,附上早先的重定向URI,向受權服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。在發出請求時,受權服務器對客戶端進行身份驗證。請求參數包含受權代碼、用於得到驗證的受權代碼的重定向URI、標識客戶端身份的client idclient secret
  • (E)受權服務器對客戶端進行身份驗證,驗證受權代碼,並確保所收到的重定向URI與用於在步驟(C)中對客戶端重定向的URI相匹配,若是有效,受權服務器將發送訪問令牌access token和刷新令牌refresh token(可選)。

接着來介紹下各個步驟所需的參數spa

對於步驟A,客戶端申請受權請求的URI,包含如下參數:

  • response_type受權類型。必選項,其值固定爲code
  • client_id客戶端id。必選項,用於標識受權服務器中已註冊的客戶端。
  • redirect_uri重定向URI。可選項,若是不填寫則使用註冊在受權服務器端與client_id對應的redirect_uri。
  • scope申請的權限範圍,如readwrite。可選項,若是申請的請求訪問超出受權服務器定義的可操做範圍則會失敗。
  • state表示客戶端當前狀態。可選項,能夠指定任意值,受權服務器會原封不動地返回這個值。

eg:

 

C步驟中,服務器迴應客戶端的URI,包含如下參數:

  • code受權碼。必選項,受權碼必須在頒發後很快過時以減少泄露風險,建議最長時間設爲10分鐘,客戶端只能使用該碼一次,不然會被受權服務器拒絕。該碼與client id和重定向URI,是一一對應關係。
  • state若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

eg:

 

D步驟中,客戶端向認證服務器申請令牌的HTTP請求,包含如下參數:

  • grant_type許可類型(受權模式)。必選項,此處固定值爲authorization_code
  • code上一步得到的受權碼。必選項。
  • redirect_uri表示重定向URI。必選項,且必須與A步驟中的該參數值保持一致。
  • client_id表示客戶端ID,必選項。

eg:

 

E步驟中,認證服務器發送的HTTP回覆,包含如下參數:

  • access_token表示訪問令牌。必選項。
  • token_type表示令牌類型。該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。
  • expires_in表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
  • refresh_token表示更新令牌。可選項,用來獲取下一次的訪問令牌。
  • scope表示權限範圍。可選項,若是與客戶端申請的範圍一致,此項可省略。

eg:

 

簡化模式(implicit

簡化模式(implicit grant type)不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"受權碼"這個步驟,所以得名。全部步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不須要認證。具體步驟可參閱RFC6749 4.2節。

密碼模式(resource owner password credentials

密碼模式中,用戶向客戶端提供本身的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要受權。
在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼。這一般用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品。而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。可參閱RFC6749 4.3節。

客戶端模式(client credentials

客戶端模式(Client Credentials Grant)指客戶端以本身的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端註冊,客戶端以本身的名義要求"服務提供商"提供服務,其實不存在受權問題。可參閱RFC6749 4.4節。

基於Github登陸的受權碼模式例子

前文提到了一個Github登陸留言的例子,假設咱們要使用OAuth2.0協議搭建一個網站,利用Github做爲受權和資源服務器,實現第三方登陸功能。
轉載)現概況一下主要流程:

1) 網站和Github之間的協商

Github會對用戶的權限作分類好比讀取倉庫信息的權限、寫入倉庫的權限、讀取用戶信息的權限、修改用戶信息的權限等等。若是我想獲取用戶的信息,Github會要求我,先在它的平臺上註冊一個應用,在申請的時候標明須要獲取用戶信息的哪些權限,而且在申請的時候填寫你的網站域名,Github只容許在這個域名中獲取用戶信息。

此時個人網站已經和Github之間達成了共識,Github也給我發了兩張門票,一張門票叫作Client Id,另外一張門票叫作Client Secret

2)用戶和Github之間的協商

用戶進入個人網站,點擊github登陸按鈕的時候,個人網站會將Github給個人Client Id交給用戶,讓他進入Github受權界面,若是此時用戶沒有登陸,Github會提示登陸(固然這不是OAuth2.0客戶端部分應該關注的)。假設用戶已經登陸Github,那麼Github看到用戶手中的門票,就知道是個人網站讓他過來的,因而就把個人網站獲取的權限擺出來,並詢問用戶是否容許網站獲取這些權限。

 

若是用戶贊成,在受權頁面點擊了確認受權後,頁面會跳轉到我預先設定的 redirect_uri並附帶一個蓋了章的門票code

 

這個時候,用戶和 Github 之間的協商就已經完成,Github 也會在本身的系統中記錄此次協商,表示該用戶已經容許在個人網站訪問上直接操做和使用他的部分資源。

3)告訴Github個人網站要來訪問

第二步中,咱們已經拿到了蓋過章的門票code,但這個code 只能代表,用戶容許個人網站從github上獲取該用戶的數據,若是我直接拿這個code去github訪問數據必定會被拒絕,由於任何人均可以持有code,github並不知道code持有方就是我本人。

還記得以前申請應用的時候github給個人兩張門票麼,Client Id在上一步中已經用過了,接下來輪到另外一張門票Client Secret

 

拿着用戶蓋過章的code和可以標識我的身份的client_idclient_secret去拜訪 github,拿到最後的綠卡access_token

 

4)用戶開始使用Github帳號在個人網站上留言

 

上一步github已經把最後的綠卡access_token給我了,經過github提供的 API 加綠卡就可以訪問用戶的信息了,能獲取用戶的哪些權限在response 中也給了明確的說明,scopeusergist,也就是隻能獲取user組和gist組兩個小組的權限,user組中就包含了用戶的名字和郵箱等信息了。

轉發自: https://blog.csdn.net/sunqiujing/article/details/82756752

相關文章
相關標籤/搜索