OAuth2.0認證流程原理

導讀

大家也許都有過這樣的體驗,我們登錄一些不是特別常用的軟件或網站的時候可以使用QQ、微信或者微博等賬號進行授權登陸。例如我們登陸豆瓣網的時候,如果不想單獨註冊豆瓣網賬號的話,就可以選擇用微博或者微信賬號進行授權登錄。這樣的場景還有很多,例如登錄微博、頭條等網站,也都可以選擇QQ或者微信登錄的方式。

那麼這樣的第三方登陸方式到底是怎麼實現的呢?難道是騰訊把我們QQ或者微信的賬戶信息賣給了這些網站不成?很顯然,騰訊是不會這麼幹的,而這種登錄方式的實現就是我們這篇文章中要給大家介紹的OAuth2.0的認證方式。類似地,在公司內部,如果公司有多套不同的軟件系統,例如我們日常使用的GitLab代碼管理、公司內網系統、財務報銷系統以及很多業務系統的管理後臺,是不是也可以實現一個員工賬號就能授權訪問所有以上這些系統,而不需要每個系統都開通單獨的賬號,設置獨立的密碼才行呢?實際上在很多公司都是可以實現這種效果的,這也就是我們通常所說的SSO單點登錄系統。

在接下來的內容中,碼農哥會先給大傢俱體介紹下OAuth2.0的基本原理,然後再通過Spring Boot實現一套遵循OAuth2.0規範的SSO單點登錄系統!

什麼是OAuth2.0?

OAuth2.0是一種允許第三方應用程序使用資源所有者的憑據獲得對資源有限訪問權限的一種授權協議。例如在前面的例子中,通過微信登錄豆瓣網的過程,就相當於微信允許豆瓣網作爲第三方應用程序在經過微信用戶授權後,通過微信頒發的授權憑證有限地訪問用戶的微信頭像、手機號,性別等受限制的資源,從而來構建自身的登錄邏輯。

需要說明的是在OAuth2.0協議中第三方應用程序獲取的憑證並不等同於資源擁有者持有的用戶名和密碼,以上面例子來說微信是不會直接將用戶的用戶名、密碼等信息作爲憑證返回給豆瓣的。這種授權訪問憑證一般來說就是一個表示特定範圍、生存週期和其訪問權限的一個由字符串組成的訪問令牌,也就是我們常說的token。在這種模式下OAuth2.0協議中通過引入一個授權層來將第三方應用程序與資源擁有者進行分離,而這個授權層也就是我們常說的“auth認證服務/sso單點登錄服務器”。

爲了便於理清認證流程中的各個角色,在OAuth2.0協議中定義了以下四個角色:

1)、resource owner(資源擁有者)

即能夠有權授予對保護資源訪問權限的實體。例如我們使用通過微信賬號登陸豆瓣網,而微信賬號信息的實際擁有者就是微信用戶,也被稱爲最終用戶。

2)、resource server(資源服務器)

承載受保護資源的服務器,能夠接收使用訪問令牌對受保護資源的請求並響應,它與授權服務器可以是同一服務器,也可以是不同服務器。在上述例子中該角色就是微信服務器。

3)、client(客戶端)

代表資源所有者及其授權發出對受保護資源請求的應用程序。在上面的例子中豆瓣網就是這樣的角色。

4)、authorization server(授權服務器)

認證服務器,即服務提供商專門用來處理認證授權的服務器。例如微信開放平臺提供的認證服務的服務器。

OAuth2.0協議流程

在瞭解了OAuth2.0協議的基本概念後,接下來讓我們一起以程序員的視角(NB點的叫法又叫上帝視角)來分析下OAuth2.0的運行流程。還是以微信授權登陸豆瓣網舉例,流程如下:

上圖通過對微信授權登錄豆瓣網過程的分析,已經比較細節的描述了OAuth2.0的運行流程了,大致說明如下:

 

  1. 首先微信用戶點擊豆瓣網微信授權登錄按鈕後,豆瓣網會將請求通過URL重定向的方式跳轉至微信用戶授權界面;

  2. 此時微信用戶實際上是在微信上進行身份認證,與豆瓣網並無交互了,這一點非常類似於我們使用網銀支付的場景;

  3. 用戶使用微信客戶端掃描二維碼認證或者輸入用戶名密碼後,微信會驗證用戶身份信息的正確性,如正確,則認爲用戶確認授權微信登錄豆瓣網,此時會先生成一個臨時憑證,並攜帶此憑證通過用戶瀏覽器將請求重定向回豆瓣網在第一次重定向時攜帶的callBackUrl地址;

  4. 之後用戶瀏覽器會攜帶臨時憑證code訪問豆瓣網服務,豆瓣網則通過此臨時憑證再次調用微信授權接口,獲取正式的訪問憑據access_token;

  5. 在豆瓣網獲取到微信授權訪問憑據access_token後,此時用戶的授權基本上就完成了,後續豆瓣網要做的只是通過此token再訪問微信提供的相關接口,獲取微信允許授權開發的用戶信息,如頭像,暱稱等,並據此完成自身的用戶邏輯及用戶登錄會話邏輯;

 

在上述流程中比較關鍵的動作是用戶怎麼樣才能給Client(豆瓣網)授權,因爲只有有了這個授權,Client角色纔可以獲取訪問令牌(access_token),進而通過令牌訪問其他資源接口。而關於客戶端如何獲得授權的問題,在OAuth2.0中定義了四種授權方式,目前微信授權登錄使用的是其中一種比較常用的模式authorization_code模式。

OAuth2.0客戶端授權模式

OAuth2.0定義了四種授權模式,它們分別是:

  • 授權碼模式(authorization code)

  • 簡化模式(implicit)

  • 密碼模式(resource owner password credentials)

  • 客戶端模式(client credentials)

下面我們就分別來分析下這四種客戶端授權模式的流程和特點吧!

授權碼模式(authorization code)

授權碼模式(authorization code)是功能最完整、流程最嚴密的授權模式。它的特點是通過客戶端的後臺服務器,與“服務提供商”的認證服務進行互動(如微信開放平臺),我們前面以微信賬號登錄豆瓣網的流程就是授權碼模式的實現。這種模式下授權代碼並不是客戶端直接從資源所有者獲取,而是通過授權服務器(authorization server)作爲中介來獲取,授權認證的過程也是資源所有者直接通過授權服務器進行身份認證,避免了資源所有者身份憑證與客戶端共享的可能,因此是十分安全的。

例如,微信用戶授權登錄豆瓣網的過程中,微信授權認證是直接在微信的網站上進行的,即便是輸入用戶名密碼也只有微信授權認證服務器可以獲取,因此豆瓣網是感知不到的,從而避免了微信用戶賬號信息在第三方網站泄露的風險。

由於授權碼模式的認證方式與前面微信登錄豆瓣網的過程是一致的,因此就不在單獨進行流程敘述了!

簡化模式(implicit grant type)

簡化模式是對授權碼模式的簡化,用於在瀏覽器中使用腳本語言如JS實現的客戶端中,它的特點是不通過客戶端應用程序的服務器,而是直接在瀏覽器中向認證服務器申請令牌,跳過了“授權碼臨時憑證”這個步驟。其所有的步驟都在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不需要認證。如果我們使用此種授權方式來實現微信登錄豆瓣網的過程的話,流程如下:

從上面的流程中可以看到在第4步用戶完成授權後,認證服務器是直接返回了access_token令牌至用戶瀏覽器端,而並沒有先返回授權碼,然後由客戶端的後端服務去通過授權碼再去獲取access_token令牌,從而省去了一個跳轉步驟,提高了交互效率。

但是由於這種方式訪問令牌access_token會在URL片段中進行傳輸,因此可能會導致訪問令牌被其他未經授權的第三方截取,所以安全性上並不是那麼的強壯。

密碼模式(resource owner password credentials)

在密碼模式中,用戶需要向客戶端提供自己的用戶名和密碼,客戶端使用這些信息向“服務提供商”索要授權。這相當於在豆瓣網中使用微信登錄,我們需要在豆瓣網輸入微信的用戶名和密碼,然後由豆瓣網使用我們的微信用戶名和密碼去向微信服務器獲取授權信息。

這種模式一般用在用戶對客戶端高度信任的情況下,因爲雖然協議規定客戶端不得存儲用戶密碼,但是實際上這一點並不是特別好強制約束。就像在豆瓣網輸入了微信的用戶名和密碼,豆瓣網存儲不存儲我們並不是很清楚,所以安全性是非常低的。因此一般情況下是不會考慮使用這種模式進行授權的。

假設微信登錄豆瓣網的過程使用了此種客戶端授權模式,其流程如下:

 

 

 

以上模式邏輯主要在服務器端實現,無法避免客戶端應用程序對授權方身份信息的存儲,所以一般情況下是不會採用這種授權模式的。

客戶端模式(client credentials)

客戶端模式是指客戶端以自己的名義,而不是以用戶的名義,向“服務提供方”進行認證。嚴格地說,客戶端模式並不屬於OAuth2.0協議所要解決的問題。在這種模式下,用戶並不需要對客戶端授權,用戶直接向客戶端註冊,客戶端以自己的名義要求“服務提供商”提供服務。

這種類似於之前共享單車比較火的情況下,出現的全能車的模式,即用戶向全能車註冊,全能車以自己平臺設立的共享賬戶去開各種品牌的單車。


綜上所述,雖然在OAuth2.0協議中定義了四種客戶端授權認證模式,但是實際上大部分實際應用場景中使用的都是授權碼(authorization code)的模式,如微信開放平臺、微博開放平臺等使用的基本都是授權碼認證模式。

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