淺談OAuth2.0

OAuth是一個關於授權(authorization)的開放網路標準,在全世界得到廣泛應用,目前的版本是2。0版。OAuth不是一個認證協議,這點不要搞混。

原因

為什麼需要OAuth2。0?

資源擁有者(RO)在資源伺服器(RS)上存了一些照片,RO想透過客戶應用列印這些照片。想訪問RS上的照片,必須有使用者授權才可以,傳統方法是RO將自己在RS上的賬號、密碼提供給客戶應用,然後客戶應用就可以訪問RS上的資源了。

淺談OAuth2.0

但這樣會有很多問題:

客戶應用為了後續的服務,會儲存使用者的密碼,這樣很不安全。

資源伺服器不得不部署密碼登入,而我們知道,單純的密碼登入並不安全。

客戶應用擁有了獲取使用者儲存在資源伺服器所有資料的權力,使用者沒法限制客戶應用獲得授權的範圍和有效期。

使用者只有修改密碼,才能收回賦予客戶應用的權力。但是這樣做,會使得其他所有獲得使用者授權的第三方應用程式全部失效。

只要有一個第三方應用程式被破解,就會導致使用者密碼洩漏,以及所有被密碼保護的資料洩漏。

OAuth2。0就可以解決這個問題。

設計

OAuth2。0能夠基於令牌Token的授權,在無需暴露使用者密碼的情況下,使應用能夠獲取對使用者資料的有限訪問許可權。

OAuth2。0主要是增加了一層授權伺服器(AS),客戶應用最終從授權伺服器獲取Token,然後使用Token獲取資源伺服器上的資源。

這樣做好處有:

更安全,客戶端不接觸使用者密碼

針對Token可以設定壽命、訪問許可權

資源伺服器和授權伺服器進行解耦(理論上授權伺服器和資源伺服器來自同一方)

淺談OAuth2.0

授權型別

OAuth2。0有四種授權型別。

淺談OAuth2.0

授權碼模式

授權碼模式(authorization code)是功能最完整、流程最嚴密的授權模式。它的特點就是透過客戶應用的後臺伺服器,與資源伺服器的認證伺服器進行互動。

淺談OAuth2.0

互動圖為:

淺談OAuth2.0

假設使用者想透過瀏覽器,使用雲列印功能,列印資源伺服器裡的照片。使用者透過瀏覽器在雲列印應用上發起列印請求,雲打印發現自己沒有許可權訪問,返回302讓使用者先授權,該請求最終轉發到授權伺服器上,授權伺服器會要求使用者輸入賬號密碼,使用者輸入完成後,給客戶應用授予限定許可權。授權伺服器生成的code會根據最初請求中提供的redirect_uri到雲列印應用,這樣客戶應用就能獲取到code。雲列印應用使用code去授權伺服器獲取token,獲得後用便可使用該token去資源伺服器獲取指定資源。

簡化模式

簡化模式(implicit grant type)不透過第三方應用程式的伺服器,直接在瀏覽器中向認證伺服器申請令牌,跳過了“授權碼”這個步驟,因此得名。所有步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不需要認證。

淺談OAuth2.0

簡化模式和授權碼模式相比,不再使用授權碼,User-Agent(瀏覽器)也能知道Token值,增加了風險。

密碼模式

密碼模式(Resource Owner Password Credentials Grant)中,使用者向客戶端提供自己的使用者名稱和密碼。客戶端使用這些資訊,向“服務商提供商”索要授權。

在這種模式中,使用者必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在使用者對客戶端高度信任的情況下,比如客戶端是作業系統的一部分,或者由一個著名公司出品。而認證伺服器只有在其他授權模式無法執行的情況下,才能考慮使用這種模式。

淺談OAuth2.0

客戶端模式

客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以使用者的名義,向“服務提供商”進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,使用者直接向客戶端註冊,客戶端以自己的名義要求“服務提供商”提供服務,其實不存在授權問題。這種模式一般用於內部伺服器之間通訊。

淺談OAuth2.0

選擇

上面講了OAuth2。0的四種模式,對於不同的客戶應用選擇哪種模式,可以參考如下方案:

淺談OAuth2.0

總結

OAuth已經是實際上的標準,另外也有很多框架可以支援OAuth2。0,大家如果有興趣,可以動手實現一下。

資料

OAuth 2。0 的四種方式

一張圖搞定OAuth2。0

理解OAuth 2。0

認證 & 授權 1。 OAuth2授權

最後

大家如果喜歡我的文章,可以關注我的公眾號(程式設計師麻辣燙)

我的個人部落格為:https://shidawuhen。github。io/

往期文章回顧:

設計模式

招聘

思考

儲存

算法系列

讀書筆記

小工具

架構

網路

Go語言