8種至關重要OAuth API授權流與能力

本文由公衆號EAWorld翻譯發表,轉載需註明出處。

作者:Daniel Lindau

譯者:白小白

原題:8 Vital OAuth Flows and Powers

原文:http://t.cn/Ew5Fu3h

全文5972字,閱讀約需要10分鐘

目錄:

一、OAuth是什麼?什麼是“流”?

二、授權流因用例不同而異

三、獲取令牌

四、令牌管理

五、爲什麼區分OAuth流很重要

(注:本文的原文,包括部分參考內容需要以不可描述的方式訪問。)

在本文中,Curity的Daniel Lindau概述了重要的OAuth授權流程和能力。

API領域需要授權驗證來保證數據的安全,這是現代API設計理念的一種必然趨勢。因此,實現正確的授權系統至關重要,甚至可能比需要處理授權的API本身更加重要。

OAuth是一個強大的解決方案。然而,與任何工具一樣,OAuth的強大有賴於用戶對其能力的理解。理解OAuth是什麼,至少對每個特定的授權流程有一個大體瞭解是非常重要的。在這篇文章中,我們將介紹OAuth,並簡要介紹每種授權流程的概念。我們將瞭解每個流程適用的時機和具體應用。

一、OAuth是什麼?什麼是“流”?

雖然可能無需贅言,但我們最好還是先了解一下OAuth的基本概念。確切地說,OAuth是基於互聯網的代理和授權的開放標準。OAuth的應用場景通常是需要代表用戶訪問某些資源的客戶端。爲了完成這一代理過程,OAuth需要發佈訪問令牌(Access Token)。令牌的存在表示用戶允許客戶端作爲用戶的代理訪問相關數據。對此令牌的請求、授予和生命週期管理通常被稱爲“流”,這一術語將在本文中大量使用。

白小白:

OAuth是一個關於授權的開放標準,允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。參考 http://t.cn/Ewt7pYI。

這裏的用戶,也就是資源所有者,而第三方應用,就是客戶端,而擁有了令牌的客戶端,在訪問相關資源時,就相當於用戶的代理。

第一版OAuth最初創建於2007年,是作爲在Twitter API上處理身份驗證的一種方式,此後,它在從企業級代碼庫到私有項目的各種應用程序中變得非常流行。第二版OAuth 2.0,已經成爲保障API安全的事實標準。

二、授權流因用例不同而異

OAuth規範接受多種獲取和驗證令牌的方法,但並不是所有流對所有類型的客戶端都是普適的。OAuth規範定義了公共和私有客戶端,這種劃分,取決於客戶端安全存儲其憑據的能力。私有客戶端通常是具有後端的應用程序,可以保留用於身份驗證的密鑰。公共客戶端無法安全存儲密鑰,比如,通常沒有後端的單頁面應用程序(Single Page Application,簡稱SPA)。

舉例來說,帶着後端的Web應用被視爲私有客戶端,而單頁應用程序被認爲是公共客戶端。後端可以安全地存儲密鑰,而SPA開放一切數據。

移動客戶端分類比較棘手,因爲他們通常都很擅長存儲密鑰,但很難給他們一個祕鑰。受到通過應用程序商店分發應用程序的方式的制約,很難令OAuth服務器信任某個客戶端代表了正確的應用程序而對客戶端以某種方式進行身份驗證。由於這個原因,移動客戶端更多作爲公共客戶端來進行考量。通過使用其他獲取憑據的方法,如動態客戶註冊,也可以將移動客戶端轉變成私有客戶端。稍後會有更多的描述。

白小白:

SPA是一個相對比較難理解的概念,如果與多頁面應用中的Ajax調用相比的話。強行理解的話,SPA將會打破MVC的模式區隔,全部的處理邏輯都是在瀏覽器端進行的,也就是說,當加載完一個單頁面應用之後,所有的相關源碼也就在瀏覽器端了。因此,不可能在這種情況下給客戶端一個密鑰,因爲那必然導致安全問題。同樣的,移動應用程序的所有處理邏輯在安裝好的一刻也是完全下載到移動設備的。但我的理解是,這兩者僅在面對OAuth的場景時才存在這樣的限制。畢竟,我們是知道,有很多移動端應用是支持用戶名密碼式的登陸方式的,也有很多應用支持諸如微信這樣的第三方授權登陸。

三、獲取令牌

在相關規範中定義的許多授權流中,有四種基本流程用於獲取OAuth中的令牌。在這裏,我將就這幾個基本流程和其他我認爲比較重要的流程進行一些描述。

1.代碼流

認證代碼授權(Authorization Code Grant),或代碼流,最廣泛使用的OAuth流。要使用代碼流獲得令牌,客戶端只需將瀏覽器重定向到服務器,就會向OAuth服務器發送授權請求。OAuth服務器確保對用戶進行身份驗證,並提示用戶批准授權。當用戶批准時,短時代碼(CODE)是發給客戶的。此代碼可視爲一次性密碼,或臨時碼。客戶端接收到此代碼,現在可以在瀏覽器之外的經過身份驗證的後端調用中使用它,並將其交換爲令牌。

這裏要提到的一件事是,用戶將只向OAuth服務器提供其憑據。用戶不必嚮應用程序提供憑據,它只需將憑證輸入到它已經知道並信任的服務器。這是OAuth着手解決的一件事。

另一個好處是令牌是通過瀏覽器傳遞,這使得竊取變得更加困難,而且由於交換令牌的調用是經過身份驗證的,所以服務器可以確保將令牌傳遞給正確的客戶端。

通常,代碼流還將允許您接收刷新令牌,在訪問令牌過期之後,允許客戶端在不需要用戶確認的情況下獲得新的訪問令牌。代碼流只應由私人客戶端使用。因爲客戶端需要在交換代碼時向服務器端提供自身的密鑰來進行身份驗證。

白小白:

認證代碼授權的最典型示例是微信網頁授權。我們在很多的第三方應用上可以通過微信網頁授權來獲得微信頭像和暱稱來登陸應用。第三方應用客戶端通過提供APPID來向微信服務器發起請求,會跳到一個頁面詢問用戶是否確認“獲得暱稱和頭像信息”,獲得確認後微信將返回CODE。然後客戶端附加SECRET和APPID再向微信獲取ACCESS_TOKEN,而後再通過ACCESS_TOKEN和OPENID拉取暱稱、頭像等信息。在此過程中:

1、用戶只向微信提供了相關憑證(OPENID),而沒有向第三方應用提供

2、刷新令牌的過程不需要經過用戶確認。

詳細示例說明:http://t.cn/R9zOQQj

代碼流客戶端由瀏覽器和後端兩部分組成。

2.隱式流

隱式流(Implicit Flow)不像代碼流那麼複雜。它以與代碼流相同的方式開始,客戶端向OAuth服務器發出授權請求。用戶對委託進行身份驗證和批准,但是OAuth服務器不會發出CODE,而是返回訪問令牌進行響應。

當然,這裏的缺點是令牌是完全可見的,而且由於它在瀏覽器中,客戶端在處理令牌的過程中容易受到安全攻擊。

隱式流是爲無法自行驗證的公共客戶端創建的。因此,相關的授信過程依賴於一個名爲redirect_uri的參數。OAuth服務器需要爲客戶端註冊一個URL,用來發送響應。僅有這個URL會發出響應,因此,即使惡意應用程序僞裝成用戶啓動代理進程,響應也將始終返回到真正的應用程序。

由於這是針對公共客戶端的,因此將不會發出刷新令牌。這意味着只有讓用戶參與才能接收新的訪問令牌。

白小白:

實際上隱式流在很多文檔中也稱爲簡化流,相對於認證碼授權流,少了第一個獲取CODE的過程。QQ的授權登陸的Client-Side模式採用的就是隱式流授權。在第三方網站或者應用中放置“QQ登陸按鈕”,然後在用戶點擊後會向服務器發出請求獲取ACCESS_TOKEN,這個請求中只會附加用戶的APPID。更多內容可參考如下鏈接:

http://t.cn/EwtAaVz

隱式流:整個流程發生在瀏覽器中。

3.客戶端憑證流

客戶端憑證流(Client Credentials Flow)中,不涉及用戶參與。這是一種嚴格限定爲服務器與服務器之間的通信的流程。服務器需要作爲自身訪問API。因此,不涉及瀏覽器,並且需要一個私有客戶端。爲了得到一個存取令牌,客戶端只需將其憑據傳遞給OAuth服務器並接收令牌即可。

此流中不發出刷新令牌,因爲客戶端無論如何都可以使用其憑據檢索新的訪問令牌。

白小白:

所謂客戶端所需要的憑據,就微信公衆平臺的場景來說,就是APPID和SECRET。CCF的授權的服務器TO服務器模式有三層含義,按照官方文檔,其一是非交互性的應用資源 ,或者在某些場合可以理解爲只讀的應用資源,儘管是隻讀的信息,但又不希望所有人都可以訪問時,就可以採用這種方式。其二是通過這種方式授權訪問的是與用戶個人無關的相關信息,也就是不需要有用戶點擊“允許獲取暱稱頭像”這個過程。微信公衆平臺的很多API即是此類,如獲得獲取用戶增減的統計數據。但顯然微信公衆平臺還有很多違反第一類“只讀”場景的例子,比如添加刪除圖文素材等。這就引出了第三種應用場景,即由本人創建的服務,仍舊由本人的其他服務進行調用的場合。微信公衆平臺的相關信息可以看作是由騰訊創建但只屬於公衆號運營者所有的資源,而在運營者獲取相關信息或進行操作時仍舊需要採用授權的方式來確認安全性。

客戶憑證流:客戶端根據令牌端點進行身份驗證。不涉及用戶確認過程。

4.資源所有者密碼憑據流

資源所有者密碼憑據流(Resource Owner Password Credentials Flow)非常簡單。客戶端收集用戶的憑據(用戶名和密碼),並將它們與自己的客戶端憑據一起傳遞。服務器以令牌和可選的刷新令牌來進行響應。很簡單對吧?但是有一個“但是”,而且很重要。

ROPC這個流程違背了OAuth的目的之一,即用戶必須將其憑據交給應用程序客戶端,因此無法控制客戶端如何使用它。如果可以使用其他流程,則不建議使用該流。它只在規範中指定以便處理遺留遷移系統的案例。使用ROPC時必須小心謹慎。一個例子可以是企業級桌面應用程序,這類應用不經常更新,但仍需要訪問API平臺。

我們不建議使用它,但是如果您真的需要的話:這個流只適用於私有客戶端,並且客戶端可以獲得一個刷新令牌。

白小白:

聽起來提供用戶名和密碼來獲得令牌和客戶憑證流的提供APPID和SECRET獲得令牌沒什麼區別。但實際上,此前的授權流,用戶或者客戶端只與授權服務器進行交互,而不需要向客戶端應用程序提供任何個人信息。而ROPC要求你在客戶端中輸入個人信息,從而可能帶來用戶隱私的泄漏。所謂遺留系統的應用場景,比較典型的是你升級後端API服務的驗證架構,在不改動舊版客戶端的情況下,使用用戶名和密碼來獲得令牌是最方便的,此時就需要使用ROPC方式。

ROPC:客戶端將用戶憑據連同自己的憑據一起發送。

5.動態客戶端註冊

雖然並非OAuth核心規範定義的流程,動態客戶端註冊(Dynamic Client Registration,後文簡稱爲DCR)解決了移動客戶端這一重要的應用場景。由於移動應用程序是通過應用程序商店分發的,因此很難給它們一個唯一標識的證書,因此移動客戶端通常被標記爲公共的客戶端。DCR嘗試對此進行彌補的方式是,客戶端自我註冊,以及在安裝時請求唯一的憑據。DCR的工作方式是讓客戶端向OAuth服務器發送註冊令牌,OAuth服務器生成一組憑據並將它們返回給客戶端。然後,這些憑據可以在代碼流中使用,客戶機可以對自己進行身份驗證。

註冊令牌可以通過多種方式獲得。可以讓用戶在隱式流中自行驗證,也可以基於預先分發的祕鑰使用客戶端憑據流。

除了移動端應用場景之外,DCR對於API管理平臺非常適用,這類平臺需要能夠爲OAuth服務器創建客戶端。

白小白:

和前面的所有模式不同的是,在DCR模式中需要進行授權的客戶端是臨時創建的,此前在授權服務器上並沒有預先定義客戶端的憑據,可以說,兩方之間是完全陌生的。比如在手機上安裝一個應用程序,不可能爲這個程序附加一個固定的密鑰,來識別這個程序的身份,因爲代碼可能採用反編譯等方式破解。再比如在API管理平臺中,新創建了一個應用,這個應用的用戶也需要獲得令牌。而應用是新創建的,授權服務器並不知曉其存在。關於這種模式,規範中並未提供固定的實現方式。以下地址的實現草案和相關內容,可以參考:

http://t.cn/EwtbhBc

http://t.cn/EwtbyOM

6.輔助令牌流

輔助令牌流(Assisted Token Flow)還處於草案階段,並不是基本流程的一部分,但值得一提。它是OAuth的同級規範,試圖使單頁應用程序獲得令牌的過程其更容易實現。對於這些類型的應用程序,很難處理隱式流,因爲它嚴重依賴重定向。相反,輔助令牌流定義了與隱式流類似的流程,不同的是,使用iFrame和postMessage作爲通訊的方式。

在這裏閱讀更多:《輔助令牌流:單頁應用程序中OAuth集成的答案》(http://t.cn/EwtoblI)

白小白:

單頁面應用的最顯著特徵是頁面本身在初次加載後是不進行頁面的刷新的,因此無法完成一個向授權服務器的的重定向來獲得令牌,輔助令牌流的解決方案就是將代碼流和隱式流等相關處理嵌入一個iFrame中進行(在我看來,這種流程才應該叫隱式流,狗頭表情參見)。這種方式怎麼說都不算高級,而且還會進一步加劇單頁面應用本身的SEO問題。但還沒有看到有更好的解決方案。

四、令牌管理

7.自省

自省(Introspection)是詢問OAuth 服務器令牌是否有效的方法。訪問令牌通常通過引用來傳遞,這意味着除了OAuth服務器之外,它們對任何人都沒有任何意義。自省客戶端通常是API或者API網關相關形態。自省是一種簡單認證調用,客戶端發送令牌,服務端響應屬於令牌的數據,如過期時間、標題等。

白小白:

OAuth.com上的文檔是這樣講的,“ OAuth2.0核心規範沒有定義資源服務器應該如何驗證訪問令牌的特定方法,只是提到它需要資源和授權服務器之間的協調。在某些情況下,特別是對於小型服務,兩個端點都是同一個系統的一部分,並且可以在內部(例如在數據庫中)共享令牌信息。如果在兩個端點位於不同服務器上的大型系統中,將導致兩臺服務器之間的通信採用專有和非標準協議” 。這個過程相當於,大哥和二哥是兄弟,然後有個張三拿着二哥的口信說讓大哥借3000塊錢,大哥總要和二哥問問這事是真是假。就其含義來說,與其譯爲自省還不如譯爲檢查或者令牌檢查,但那與原詞含義差距太大。我的理解是,這個檢查過程僅發生在資源服務器和授權服務器之間,而這兩者相當於同一系統中互相信賴的兩方,也就是,都是自己人,因此英文原文是Introspection。

8.撤銷

撤銷(Revocation)是OAuth重要的能力之一。如果沒有OAuth,用戶一旦將其憑據泄露給應用程序,就無法收回這一確認。唯一的辦法是更改密碼,然而這將帶來更大的副作用,比如,密碼修改後,相關應用將無法訪問用戶的賬戶。

使用OAuth,用戶可以通過撤銷令牌的方式隨時決定收回確認。在OAuth中,有兩種撤銷選項。可以撤銷訪問令牌,這將被視作是當前會話的結束。如果存在刷新令牌,則該令牌仍然有效。撤銷刷新令牌將使刷新令牌無效,並使其附帶的任何活動的訪問令牌無效。

使用經過身份驗證的調用執行實際的撤銷操作,這一過程由客戶端完成。經過身份驗證,公共客戶端也可以執行撤銷。

白小白:

這裏面涉及“代理”的概念,一次代理代表客戶端以授權的用戶身份執行某種操作。而一次代理過程中可能獲得多次令牌,包括訪問令牌和刷新令牌。

事實上可能存在3種撤銷場景:

1、如果某一個當前有效的訪問令牌被撤銷了,比如訪問訪問令牌1被撤銷,則刷新令牌1仍舊有效。

2、如果某一個當前有效的刷新令牌被撤銷了,則所有訪問和刷新令牌都會撤銷,也就是這一次代理都被撤銷

3、如果通過某一個刷新令牌X獲得了新的訪問令牌和新的刷新令牌。則對這一刷新令牌X的撤銷操作不會有任何後續效果。

參見http://t.cn/Ewtcr8X

五、爲什麼區分OAuth流很重要

在OAuth中似乎有很多類似的流,但是每個流都有其特定的用例。通過這些基本流,您應該能夠選擇與您的應用程序和場景相匹配的流。雖然這通常都是高水平的,但每一個流量都可以保證它自己的一部分。

白小白:

如果對本文的相關概念作一個梳理,大致如下。這個表格梳理了本文的6種授權流的異同,表格的目的在於讓我們以簡單的方式理解幾種流模式的區別。信息並不全面,也未必準確,僅爲個人理解。所謂簡稱,是我認爲可以簡單概括其本意的名稱。

(點擊可放大)

關於作者:Daniel Lindau是Curity的解決方案架構師。他目前的大部分工作是幫助各種規模的公司構建基於安全標準的SSO解決方案。他有作爲應用程序開發人員的背景,並且在用SAML、SCIM、OAuth2和OpenIDConnect等標準構建解決方案方面有豐富的經驗。

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