OAuth2.0第三方授權

第一章.OAuth2.0 介紹


OAuth認證

 

OAuth認證是爲了做到第三方應用在未獲取到用戶敏感信息(如:賬號密碼、用戶PIN等)的情況下,能讓用戶授權予他來訪問開放平臺(主要訪問平臺中的資源服務器Resource Server)中的資源接口。

其流程主要是:
* 1.用戶首先要保持登錄,即已認證通過的狀態
* 2.第三方應用請求用戶授權(我理解是彈出一個顯示的操作界面讓用戶確認給第三方授權)
* 3.用戶授權成功之後會向Authorization Server(認證服務器)請求“授權碼”(指authorization_code而不是最終的access_token),請求中還會攜帶redirect_uri(跳轉至第三方應用的鏈接)
* 4.獲得“授權碼”之後用戶所在的瀏覽器網頁將跳轉到redirect_uri(即第三方應用)
* 5.第三方應用攜帶“授權碼”和應用認證信息(client_id & client_secret)到Authorization Server換取access_token
* 6.第三方應用就可以在訪問開放平臺時帶上access_token

SSO單點登錄

單點登錄是指用戶在某個應用系統上登錄之後,進入其子應用或相關應用系統可以免去登錄步驟,從而實現一次登錄,到處操作。這次項目我所負責的正好是單點登錄功能模塊,所以來更新下實際項目中SSO的實現流程,我們要實現的效果是,現在有業務服務器a.com和b.com,還有SSO服務器sso.com,在a.com上完成登錄操作之後訪問b.com時是已登錄狀態。
* 1.用戶首次訪問a.com/user時,到a.com服務器獲取不到session
* 2.給用戶彈出一個SSO的登錄頁面sso.com/login.html,這個頁面會帶上兩個參數,分別是開發者平臺映射值key(即某個業務服務器在SSO所映射的key)和回調地址redirect(即登錄成功之後跳轉到的url,一般是所發起業務服務器開放的路由)
* 3.用戶輸入賬號密碼之後到SSO服務器上進行身份校驗,若校驗成功則給用戶生成一個ticket,並將該ticket值及用戶基本信息一起創建SSO服務器session
* 4.選擇某種加密方式對該請求的session進行加密之後生成一個token值,然後在回調地址redirect裏帶上token參數並跳轉回去a.com服務器。
* 5.a.com對token參數進行解析後拿到用戶基本信息和ticket值,相應地初始化本地session並將ticket值也記錄下來。
* 6.用戶再次訪問a.com/user或其他頁面的時候,到a.com上獲取session併到sso.com上校驗ticket值得有效性,兩個操作都成功之後才返回用戶信息;若校驗ticket值失敗,則重新要求用戶進行登錄操作,即從步驟1開始。
* 7.現在用戶在a.com上的登錄和訪問流程已完成,那這時用戶訪問b.com/user,到b.com上獲取不到session,則會重定向到sso.com/session,因爲之前a.com已在sso.com上登錄過,故請求sso.com/session的時候SSO服務器能將session中用戶信息和ticket值返回給b.com。
* 8.b.com獲取到用戶信息和ticket值之後和a.com做相同的事情即可,這樣就完成了單點登錄的整個流程。

SSO單點登出

單點登出則是指用戶只要在a.com服務器上進行登出操作,則在其他業務服務器如b.com上也應處於未登錄狀態,單點登錄流程的步驟6中提到每次用戶訪問業務服務器路由檢驗用戶當前狀態時不僅僅查找本地有沒有session,還要到SSO服務器上校驗ticket值的有效性,所以只要有一個業務服務器登出時令ticket失效即可。
* 1.現在用戶是登錄狀態,他從a.com進行了退出操作,則自然a.com已將其session清除。
* 2.a.com服務器同時還要攜帶ticket值發請求到sso.com將對應的記錄清除。
* 3.當訪問某個b.com某個頁面時,雖然在b.com服務器上獲取到session,此外還需要到SSO服務器上校驗一遍ticket值,而發現ticket值校驗失敗,則會提示用戶當前處於未登錄狀態。
* 4.這樣相當於b.com也已經是退出登錄,完成了單點登出的整個流程

第二章.OAuth2.0更爲具體的解釋

一. OAutho2.0 介紹


第三方登錄是應用開發中的常用功能,通過第三方登錄,我們可以更加容易的吸引用戶來到我們的應用中。現在,很多網站都提供了第三方登錄的功能,在他們的官網中,都提供瞭如何接入第三方登錄的文檔。但是,不同的網站文檔差別極大,各種第三方文檔也是千奇百怪,同時,很多網站提供的SDK用法也是各不相同。對於不瞭解第三方登錄的新手來說,實現一個支持多網站第三方登錄的功能可以說是極其痛苦。

實際上,大多數網站提供的第三方登錄都遵循OAuth協議,雖然大多數網站的細節處理都是不一致的,甚至會基於OAuth協議進行擴展,但大體上其流程是一定的。今天,我們就來看看基於OAuth2的第三方登陸功能是這樣一個流程。
OAuth協議目前已經升級到了2.0,大部分的網站也是支持OAuth2.0的,因此讓我們先看看OAuth2。

上圖中所涉及到的對象分別爲:

  • Client 第三方應用,我們的應用就是一個Client
  • Resource Owner 資源所有者,即用戶
  • Authorization Server 授權服務器,即提供第三方登錄服務的服務器,如Github
  • Resource Server 擁有資源信息的服務器,通常和授權服務器屬於同一應用

根據上圖的信息,我們可以知道OAuth2的基本流程爲:

  1. 用戶訪問第三方應用。
  2. 第三方應用請求用戶授權。(A)
  3. 用戶同意授權,並返回一個憑證(code)。(B)
  4. 第三方應用通過第二步的憑證(code)向授權服務器請求授權。(C)
  5. 授權服務器驗證憑證(code)通過後,同意授權,並返回一個資源訪問的憑證(Access Token)。(D)
  6. 第三方應用通過第四步的憑證(Access Token)向資源服務器請求相關資源。(E)
  7. 資源服務器驗證憑證(Access Token)通過後,將第三方應用請求的資源返回。(F)

二. OAuth2.0的具體實現


看完OAuth的基本流程後,大家實際上對到底如何做OAuth驗證還是不太清楚,同時,也會產生疑問,爲什麼需要兩次獲取憑證,而不是直接用戶授權拿到憑證後就直接獲取資源呢?這和OAuth的具體實現有關,讓我們來看看OAuth2的具體實現吧。

1.用戶授權

在用戶授權這一步中,我們將得到一個用戶憑證(code),我們的應用可以通過該用戶憑證(code)來和授權服務器交換一個資源訪問憑證(Access Token)。

這裏我們只討論第三方登錄功能的實現情況,經過分析,我們可以得出用戶憑證(code)具有三個特性:

  • 用戶憑證(code)需要由用戶授權,也就是說該行爲是用戶的主動行爲, 此時爲了保證用戶身份正確,實際上也需要用戶通過授權服務器的驗證(登錄操作或者已登錄狀態)
  • 用戶憑證(code)需要授權服務器頒發,因爲最終用戶憑證(code)是由授權服務器驗證的,同時用戶授權操作爲了保證用戶身份,也需要在授權服務器上進行操作,因此,用戶憑證(code)是由授權服務器進行頒發的
  • 用戶憑證(code)需要由授權服務器傳遞給我們的第三方應用,很明顯,由用戶在資源服務器上拿到憑證再手動的提交至第三方應用太麻煩,因此,當用戶主動授權行爲發生後,資源服務器需要將用戶憑證(code)發送給第三方應用。

我們以Github爲例,看看主流的第三方登錄是如何滿足上述三個特性的。

第0步. 引導用戶進行授權:

當用戶希望使用第三方登錄進行登錄時,第三方應用會通過類似下圖【快速登錄】的方式將用戶引導至授權頁面,爲了和OAuth基本流程一致,我們將這一步定義爲第0步。

第0.5步. 用戶身份驗證

當我們點擊Github的圖標,我們會進入到Github應用下面,此時實際上進行了一次用戶身份的驗證,之前沒有登錄Github的用戶需要輸入Github的賬號密碼,已登錄的用戶Github會根據Session進行身份確認。此操作我們稱爲0.5步。接下來正式進入OAuth2的流程

第1步. 用戶授權

用戶身份確認後會進入下面這個頁面,該頁面由授權服務器提供,授權服務器會告訴用戶該第三方在授權服務器中提交的相關信息(如果需要實現第三方登錄功能,第三方應用需要向Github、微博等應用中提交應用的相關信息,不同服務可能會需要審覈等不同的步驟),以及授權後第三方應用能夠獲取哪些資源。在Github中,最基礎的認證可以訪問用戶的公共信息。如果用戶同意授權,需要主動的點擊【Authorize application】按鈕。

第2步. 返回用戶憑證(code)

當用戶點擊按鈕同意授權後,授權服務器將生成一個用戶憑證(code),此時授權服務器如何將用戶憑證(code)傳遞給第三方應用呢?

當我們向授權服務器提交應用信息時,通常需要填寫一個redirect_uri,當我們引導用戶進入授權頁面時,也會附帶一個redirect_uri的信息(如https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=http%3A%2F%2Ftianmaying.com%2Foauth%2Fgithub%2Fcallback&state=XXX),當授權服務器驗證兩個URL一致時,會通知瀏覽器跳轉到redirect_uri,同時,在redirect_uri後附加用戶憑證(code)的相關信息,此時,瀏覽器返回第三方應用同時攜帶用戶憑證(code)的相關信息。授權後訪問的redirect_uri如下:

http://tianmaying.com/oauth/github/callback?code=9e3efa6cea739f9aaab2&state=XXX

這樣,第二步返回用戶憑證(code)就完成了。

2.授權服務器授權

從這一步開始,OAuth2 的授權將有兩個重大變化的發生:

用戶主動行爲結束,用戶理論上可以不需要再做任何主動的操作,作爲第三方應用的我們可以在後臺拿到資源服務器上的資源而對用戶是不可見的,當用戶的瀏覽器跳到下一個頁面時,整個OAuth2的流程已經結束
瀏覽器端行爲結束,從OAuth2 的基本流程可以看出,接下來的流程已經不需要和用戶進行交互,接下來的行爲都在第三方應用與授權服務器、資源服務器之間的交互。
我們知道瀏覽器端的行爲實際上是不安全的,甚至安全憑證的傳遞都是通過URL直接傳遞的。但是由於用戶憑證(code)不是那麼敏感,其他攻擊者拿到用戶憑證(code)後依然無法獲取到相應的用戶資源,所以之前的行爲是允許的。接下來我們看看服務器如何交互來安全的獲得授權服務器授權。

第3步. 請求授權服務器授權

要拿到授權服務器的授權,需要以下幾個信息:
* client_id 標識第三方應用的id,由授權服務器(Github)在第三方應用提交時頒發給第三方應用
* client_secret 第三方應用和授權服務器之間的安全憑證,由授權服務器(Github)在第三方應用提交時頒發給第三方應用
* code 第一步中返回的用戶憑證redirect_uri 第一步生成用戶憑證後跳轉到第二步時的地址
* state 由第三方應用給出的隨機碼

我們看到,上述信息還涉及到第三方應用的安全憑證(client_secret),因此要求OAuth要求該請求必須時POST請求,同時,還必須時HTTPS服務,以此保證獲取到的驗證憑證(Access Token)的安全性。

第4步. 拿到驗證憑證(Access Token)

當授權服務器拿到第3步中的所有信息,驗證通過後,會將Access Token返回給第三方應用。

3.訪問資源

第5步. 請求訪問用戶資源

拿到驗證憑證(Access Token)後,剩下的事情就很簡單了,資源服務器會提供一系列關於用戶資源的API,拿驗證憑證(Access Token)訪問相應的API即可,例如,在GIthub中,如果你想拿到用戶信息,可以訪問以下API:

GET https://api.github.com/user?access_token=...

注意,此時的訪問不是通過瀏覽器進行的,而是服務器直接發送HTTP請求,因此其安全性是可以保證的。

第6步. 返回資源

如果驗證憑證(Access Token)是正確的,此時資源服務器就會返回資源信息,此時整個OAuth流程就結束了。

三. 第三方登錄


看完OAuth2的資源訪問流程,我們的第三方登錄是如何做的呢?首先我們需要知道兩點:

用戶授權信息在授權服務器中是有記錄的,當用戶第一次授權給相應的第三方應用後,不需要進行再次授權
每個用戶在資源服務器中都有一個唯一的ID,第三方應用可以將其存儲起來並與本地用戶系統一一對應起來
這樣,當用戶第一次授權並且註冊後(主動註冊或者第三方應用使用用戶信息默認註冊),當再次點擊第三方登錄的按鈕,瀏覽器跳轉到授權服務器,授權服務器通過Session找到用戶的授權信息,發現該用戶已經授權給該第三方應用,將直接跳轉到redirect_uri,此時第三方應用通過唯一的用戶ID找到相應的本地用戶,自動幫助其登錄。

這樣,就可以達到直接點擊第三方登錄按鈕,不需要任何操作,經過幾次跳轉後自動登錄的效果了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章