1. 程式人生 > >[認證授權] 3.基於OAuth2的認證(譯)

[認證授權] 3.基於OAuth2的認證(譯)

OAuth 2.0 規範定義了一個授權(delegation協議,對於使用Web的應用程式和API在網路上傳遞授權決策非常有用。OAuth被用在各鍾各樣的應用程式中,包括提供使用者認證的機制。這導致許多的開發者和API提供者得出一個OAuth本身是一個認證協議的錯誤結論,並將其錯誤的使用於此。讓我們再次明確的指出:

OAuth2.0 不是認證協議。
OAuth2.0 不是認證協議。
OAuth2.0 不是認證協議。

混亂的根源來自於在認證協議的內部實際上使用了OAuth,開發人員看到OAuth元件並與OAuth流程進行互動,並假設通過簡單地使用OAuth,他們就可以完成使用者認證。這不僅不是事情的真相,而且對服務提供商,開發人員以及終端使用者而言都是危險的事情。

本文旨在幫助潛在的身份提供者如何基於OAuth2構建使用者身份認證。實際上,如果你說“我有OAuth2,並且我需要身份認證”,那麼請繼續閱讀。

什麼是認證(Authentication)?

在使用者訪問一個應用程式的上下文環境中認證會告訴應用程式當前使用者是誰以及其是否存在。一個完整的認證協議可能還會告訴你一些關於此使用者的相關屬性,比如唯一識別符號、電子郵件地址以及應用程式說“早安”時所需要的內容。認證是關於應用程式中存在的使用者,而網際網路規模的認證協議需要能夠跨網路和安全邊界來執行此操作。

然而,OAuth沒有告訴應用程式上述任何資訊。OAuth對使用者沒有任何說明,也沒有說明如何證明他們的存在,即使他們就在那裡。對於OAuth的Client而言,它請求一個token,得到一個token,並用這個token訪問一些API。但它不知道是誰授權的應用程式,以及甚至還有一個使用者在那裡。實際上,OAuth的大部分問題在於Client和被訪問的資源之間的連線上在使用者不存在

的情況下使用這種委託訪問。這對於Client授權來說是好的,但是對於使用者身份認證來說卻非常糟糕,因為認證需要確定使用者是否存在(以及他們是誰)。

另外一個的混淆的因素,一個OAuth的過程通常包含在一些認證的過程中:資源所有者在授權步驟中向授權伺服器進行身份驗證,客戶端向令牌端點中的授權伺服器進行身份驗證,可能還有其他的。OAuth協議中的這些認證事件的存在不能夠說明OAuth協議本身能夠可靠地傳送認證。(譯註:我覺得可能作者想表達的是雖然OAuth是這些認證事件的消費者,但卻不是生產者,所以不能因為使用了認證,就等同於OAuth可以直接提供認證。)

事實證明儘管如此,還有一些事情可以和OAuth一起使用,以便在授權和授權協議之上建立

身份認證協議。幾乎在所有的這些情況下,OAuth的核心功能都將保持不變,而發生的事件是使用者將他們的身份委派給他們正在嘗試登入的應用程式。然後,客戶端應用程式成為身份API的消費者,從而找出先前授權給客戶端的使用者。以這種方式建立身份驗證的一個主要好處是允許管理終端使用者的同意,這在網際網路規模的跨域身份聯合中是非常重要的。另一個重要的好處是,使用者可以同時將訪問其他受保護的API委託給他們的身份,使應用程式開發人員和終端使用者管理更簡單。通過一個呼叫,應用程式可以找出使用者是否登入,應該呼叫什麼使用者,下載照片進行列印,並將更新發布到其訊息流。這種簡單性是非常有吸引力的,但當這兩件事情同時進行時,許多開發人員將這兩個功能混為一談。

認證(Authentication) VS 授權(Authorization) : 一個比喻

為了幫助弄清楚這件事情,可以通過一個比喻來思考這個問題:巧克力 VS 軟糖。在一開始,這兩件事情的本質是截然不同的:巧克力是一種原料,軟糖就是糖果。巧克力可以用來做許多不同的事情,甚至可以自己使用。軟糖可以由許多不同的東西製成,其中一種可能是巧克力,但是需要多種成分來製造軟糖,甚至不會用到巧克力。因此,巧克力等於軟糖是錯誤的,而巧克力等於巧克力軟糖肯定是誇大其詞的。

在這個比喻中,OAuth是巧克力。這是一個多功能的原料,對許多不同的東西是至關重要的,甚至可以自己使用。認證更像是軟糖,至少有一些成分必須以正確的方式彙集在一起​​,使其成為可能,OAuth也許是這些成分之一(可能是主要原料),但可能也根本不需要參與其中。你需要一個配方來說明說明如何組合它們。

事實上,有一些眾所周知的配方可以與特定的供應商進行合作,比如Facebook Connect、使用Twitter登入以及OpenID Connect(為Google的登入系統提供了支援)。這些配方每個都添加了一些專案到OAuth中以建立身份認證協議,比如通用的profile API。可以在沒有OAuth的情況下構建身份驗證協議嗎?當然可以,就像有很多種非巧克力軟糖一樣。但是我們今天在這裡談論的是專門針對基於OAuth2的身份認證,以及可能出現什麼問題,以及如何確保安全和美味。

使用OAuth進行認證的常見誤區

即使使用OAuth來構建身份驗證協議是非常有可能的,但是在身份提供者或者身份消費者方面,有許多事情可能會讓這些人脫節。本文中描述的做法旨在通知身份提供商的潛在的常見風險,並向消費者通報在使用基於OAuth的身份認證系統時可避免的常見錯誤。

Access Token作為身份認證的證明

由於身份認證通常發生在頒發access token的之前, 因此使用access token作為身份認證的證明是非常誘人的。然而, 僅僅擁有一個access token並沒有告訴Client任何東西。在OAuth 中, token被設計為對Client不透明(譯註:上一篇[認證授權] 2.OAuth2授權(續) & JSON Web Token中有介紹), 但在使用者身份認證的上下文環境中, Client需要能夠從token中派生一些資訊。

此問題的根源在於Client不是OAuth access token的預期受眾。相反, 它是該token的授權提出者, 而受眾實際上是受保護的資源。受保護的資源通常不能夠僅通過token的單獨存在來判斷使用者是否存在, 因為 oauth 協議的性質和設計, 在客戶端和受保護資源之間的連線上使用者是不可用的。為了應對這一點, 需要有一個針對客戶本身的假象,這可以通過定義一個雙重目的(dual-purposing)的Client可以解析和理解的access token來完成。但是由於一般的OAuth沒有為access token本身定義特定的格式貨結構,因此諸如OpenId Connect的ID Token和Facebook Connect的Signed在響應中提供一個次要的標記,它將和access token一起傳送給Client中。這可以使得Client對主要的access token保持不透明,就像常規的OAuth中的那樣。

訪問受保護的API作為身份認證的證明

由於access token可以用於獲取一組使用者屬性,因此擁有一個有效的access token作為身份認證的證明也是很誘人的。在一些情況下,這種假設是成立的,因為在授權伺服器商經過身份認證的使用者上下文中,token是剛剛被建立的。但是在OAuth中,這並不是獲取access token的唯一方法,Refresh Token和assertions(Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants:https://tools.ietf.org/html/rfc7521)可以在使用者不存在的情況下獲取access token。而在某些情況下,使用者無需身份驗證即可獲得access token(譯註:比如[認證授權] 1.OAuth2授權 - 5.4 Client Credentials Grant)。

此外,在使用者不存在後,access token通常還會存在很長時間。記住,OAuth是一個授權協議(delegation protocol),這對它的設計至關重要。這意味著,如果一個Client想要確保身份認證是有效的,那麼簡單的使用token獲取使用者屬性是不夠的,因為OAuth保護的是資源,獲取使用者屬性的API(identity API)通常沒有辦法告訴你使用者是否存在。

注入Access Token

另外一個額外的威脅(非常危險)是當Client接受來自token endpoint的token時。這可能會發生在使用implicit流程(這個流程中直接把acces token作為url的hash引數(譯註:[認證授權] 1.OAuth2 授權 - 5.2.2 Access Token Response))中,並且Client不正確的使用state引數的時候。如果應用程式在不同的元件中傳遞 access token以“共享”訪問許可權的時候,也會發生此問題。這裡的問題在於它開闢了一個注入access token到應用程式外部(並可能在應用程式外部洩露)的地方。如果Client不通過某種機制驗證access token,則它無法區分access token是有效的令牌還是攻擊的令牌。

可以通過使用Authorization code來緩解這一點,並且只能通過授權伺服器的token API(token endpoint)並使用一個state的值來避免被攻擊者猜中。

缺乏受眾限制

另外一個問題是,通過access token獲取一組使用者屬性的OAuth API通常沒有為返回的資訊的受眾做任何限制。換句話話說,很可能有一個幼稚的(naive)Client,從其他的Client拿到一個有效的token來作為自己的登入事件。畢竟令牌是有效的,對API的訪問也會返回有效的使用者資訊。問題在於沒有使用者做任何事情來證明使用者存在,在這種情況下,使用者甚至都沒有授權給幼稚的(naive)Client。

通過將Client的認證資訊與Client可以識別和驗證的識別符號一起傳遞給Client,可以緩解此問題,從而允許客戶端區分自身的身份認證與另一應用程式的身份認證。通過在OAuth的過程中直接向Client傳遞一組身份認證資訊,而不是通過受OAuth保護的API這樣的輔助機制來緩解它,從而防止Client在稍後的過程中注入未知來源的不可信的資訊。

注入無效的使用者資訊

如果攻擊者能夠攔截或者替換來自Client的一個呼叫,它可能會改變返回的使用者資訊,而客戶端卻無法感知這一情況。這將允許攻擊者通過簡單地在正確的呼叫序列中交換使用者識別符號來模擬一個幼稚的(naive)Client上的使用者。通過在身份認證協議過程中(比如跟隨OAuth的Token的頒發過程)直接從身份提供程式中獲取身份認證資訊,並通過可校驗的簽名保護身份認證資訊,可以緩解這一點問題。

每個潛在的身份提供商的不同協議

基於OAuth 身份(identity)API的最大問題在於,即使使用完全符合OAuth的機制,不同的提供程式不可避免的會使用不同的方式實現身份(identity)API。比如,在一個提供程式中,使用者識別符號可能是用user_id欄位來表示的,但在另外的提供程式中則是用subject欄位來表示的。即使這些語義是等效的,也需要兩份程式碼來處理。換句話說,雖然發生在每個提供程式中的授權是相同的,但是身份認證資訊的傳輸可能是不同的。此問題可以在OAuth之上構建標準的身份認證協議來緩解,這樣無論身份認證資訊來自何處,都可以用通用的方式傳輸。

基於OAuth的使用者認證的標準:OpenId Connect

OpenID Connect是2014年初發布的開放標準,定義了一種基於OAuth2的可互操作的方式來來提供使用者身份認證。實際上,它是眾所周知的巧克力軟糖的配方,已經被多數的專家們嘗試和測試了。應用程式不必為每個潛在的身份提供程式構建不同的協議,而是可以將一個協議提供給多個提供程式。由於OpenId Connect是一個開放標準,所以可以自由的沒有任何限制的和智慧財產權問題的來實現。

OpenId Connect是直接建立在OAuth2之上的,在大多數情況下,部署在一個基於OAuth的基礎設施之上。它還使用JOSN簽名和加密規範,用來在傳遞攜帶簽名和加密的資訊。OpenId Connect避免了上面討論的很多誤區。

ID Tokens

OpenID Connect Id Token是一個簽名的JSON Web Token(JWT:RFC7519),它和OAuth access token一起提供給Client應用程式。Id Token包含一組關於身份認證會話的宣告(claim),包括使用者的標識(sub)、頒發令牌的提供程式的識別符號(iss)、以及建立此標識的Client的識別符號(aud)。此外,Id Token還包含token的有效生存期(通常非常短)以及其他相關的上下文資訊。由於Client知道Id Token的格式,因此它能直接分析出token的內容而無需依賴外部服務。此外,OpenId Connect還頒發access token給Client,允許Client保持對token的不透明,因為這是屬於OAuth規範的一部分。最後,token本身是由提供程式的私鑰進行簽名的,除了在獲取token中受TLS的保護之外,還添加了一個額外的保護層,以防止類似的模擬攻擊。通過對此token的一些校驗檢查,Client可以保護自己免受大量常見的攻擊。

由於Id token是授權伺服器簽名的,它還提供了在authorization code(c_hash)和access token(at_hash)上新增分離簽名的位置,這些hash可以由Client來驗證,同時仍保留authorization code和access token對Client不透明的語義,從而防止這一類的注入攻擊。

應該指出的是,Client不再需要使用access token,因為Id token已經包含了處理身份認證所需的所有資訊。然而,為了保持和OAuth的相容性,OpenId Connect會同時提供Id token和acces token。

UserInfo Endpoint

除了Id token包含的資訊之外,還定義了一個包含當前使用者資訊的標準的受保護的資源。如上所述,這些資訊不是身份認證的一部分,而是提供附加的標識資訊。比如說應用程式提示說“早上好:Jane Doe”,總比說“早上好:9XE3-JI34-00132A”要友好的多。它提供了一組標準化的屬性:比如profile、email、phone和address。OpenId Connect定義了一個特殊的openid scope,可以通過access token來開啟Id token的頒發以及對UserInfo Endpoint的訪問。它可以和其他scope一起使用而不發生衝突。這允許OpenId Connect和OAuth平滑的共存。

動態服務發現以及客戶端註冊

OAuth2為了允許各種不同的部署而編寫,但是這樣的設計並沒有指定這些部署如何設定以及元件之間如何互相瞭解,在OAuth自己的世界中這是沒問題的。在使用OpenId Connect時,一個通用的受保護的API部署在各種各樣的Client和提供者中,所有這些都需要彼此互相瞭解才能執行。對於每個Client來說,不可能事先了解有關每個提供程式,並且要求每個提供者瞭解每個潛在的Client,這將大大削弱擴充套件性。

為了抵消這種情況,OpenId Connect定義了一個發現協議,它允許Client輕鬆的獲取有關如何和特定的身份認證提供者進行互動的資訊。在另一方面,還定義了一個Client註冊協議,允許Client引入新的身份提供程式(identity providers)。通過這兩種機制和一個通用的身份API,OpenId Connect可以執行在網際網路規模上執行良好,在那裡沒有任何一方事先知道對方的存在。

相容OAuth2

即使擁有這些強大的身份認證功能,OpenId Connect(通過設計)仍然與純粹的OAuth2相容,使其可以在開發人員花費最小代價的情況下部署在在OAuth系統之上。實際上,如果服務已經使用了OAuth和JOSE規範(以及JWT),該服務以及可以很好的支援OpenId Connect了。

譯註 & 原文

原文成文應該時比較早,一些資訊已經過時了,我做了部分的刪減,現在OpenId Connect已經成為了一個非常龐大的協議族了,有很多相關的輔助協議來完善認證授權的相關需求。OpenId Connect具體的資訊參見這裡:http://openid.net/connect/。本人翻譯水平一般,如有錯誤之處,歡迎指正!

備註:原文標題是“User Authentication with OAuth 2.0”,覺得有點不妥,本來很多人對於AuthenticationAuthorization的認知就有一些混淆,而OAuth2是一個Authorization協議,而不是Authentication的協議,故而在翻譯的時候調整了原文的名稱。同時提了一個Pull Request(https://github.com/aaronpk/oauth.net/pull/154),不知道會不會被接受。

相關推薦

[認證授權] 3.基於OAuth2認證

OAuth 2.0 規範定義了一個授權(delegation)協議,對於使用Web的應用程式和API在網路上傳遞授權決策非常有用。OAuth被用在各鍾各樣的應用程式中,包括提供使用者認證的機制。這導致許多的開發者和API提供者得出一個OAuth本身是一個認證協議的錯誤結論,並將其錯誤的使用於此。讓我們再次明確

Web Api Owin+Oauth2.0ClientCredentials+Jwt Token許可權認證控制

OAuth簡介 OAuth簡單說就是一種授權的協議,只要授權方和被授權方遵守這個協議去寫程式碼提供服務,那雙方就是實現了OAuth模式。 OAuth 2.0 四種授權模式: 授權碼模式(authorization code) 簡化模式(implicit) 密碼模

Web是如何工作的3:HTTP&REST

medium 方法 post ogg 兩臺 gecko 希望 種類 正常 原文地址:https://medium.freecodecamp.org/how-the-web-works-part-iii-http-rest-e61bc50fa0a 我們在第一篇文章中介紹了

Security+認證考試經驗分享——備考篇

到你 直播 信用卡 bubuko alt 快速 現在 下一步 很慢 我於11月11日參加並通過了Security+考試,下面我從兩個方面跟大家講述下我的備考和考試經過。 一、備考經歷 1. Security+官方教材怎麽用? Security+官方教材我個人覺得就兩個作

Security+認證考試經驗分享——備考篇

多選 備考 數據 屏幕 畫板 學生 需要 ceo 會有 考點: 預約的地點可以聯系預約老師,在VUE官網上也可以查詢到所在省份具體考點位置,因為Google地圖的原因,所以不能更直接看到地理位置,除非… 因為我是第一次參與這種類型的考試,提前去考場蹲了點,我覺得這很有必

Security+認證考試經驗分享——備考篇

地鐵 但是 網絡安全 個人 cti 介紹 擔心 安全管理 渠道 一、了解渠道 剛開始我是對安全方面感興趣,然後就在網上搜相關的視頻教程,就搜索到了安全牛課堂這個平臺,剛好看到安全牛課堂在推出security+課程,看到安全牛課堂對security+認證的介紹,也是從那時

OpenCV(3.2)+Python(3.6)學習(基於官方API)

1.1 Getting Started with Images   博主最近由於專案需求,需要學習OpenCV,在檢視並試驗了幾種語言之後決定用Python作為開發語言。剛開始學習也是各種網上找資料,但是網上的資料過於雜亂,最後還是覺得官方API最全面。所

CCF認證 201803-2 碰撞的小球 Python

問題描述   數軸上有一條長度為L(L為偶數)的線段,左端點在原點,右端點在座標L處。有n個不計體積的小球線上段上,開始時所有的小球都處在偶數座標上,速度方向向右,速度大小為1單位長度每秒。   當小球到達線段的端點(左端點或右端點)的時候,會立即向相反的方向移動,速度大小

微軟Windows2008 AD+NPS配合無線控制器採用PEAP認證無線客戶端的配置1

思科無線控制器支援外接Radius介面,採用思科ACS 做為Radius來認證無線客戶端只是一種應用形式。很多客戶已經部署了微軟的Windows 2003/2008伺服器並希望通過微軟的架構實現Radius功能。這是可行的,例如Windows 2003 AD + IAS即

CCF認證——201604-1折點計數C++

試題編號: 201604-1 試題名稱: 折點計數 時間限制: 1.0s 記憶體限制: 256.0MB 問題描述: 問題描述     給定

OpenCV(3.2)+Python(3.6)學習(基於官方API)

1.3 Drawing Functions in OpenCV Goal 學習如何用 OpenCV 畫各種不同的圖形。 我們將學習這些函式:cv2.line(),cv2.circle(),cv2.rectangle,cv2.ellipse(),cv2.

【Oracle 12c】CUUG OCP認證071考試原題解析30

tno eat ces 數據分析 nds table 不支持 commands 連接 30.choose the best answer Examine the commands used to create DEPARTMENT_DETAILS and COURSE_DE

【Oracle 12c】CUUG OCP認證071考試原題解析32

following primary cin into ref exce win rim val 32.choose the best answer View the Exhibit and examine the data in EMP and DEPT tables. I

【12c OCP】CUUG OCP認證071考試原題解析33

希望 any The oos rec group by max from _id 33.choose the best answer View the Exhibit and examine the structure of the ORDER_ITEMS table. E

【12c OCP】CUUG OCP認證071考試原題解析34

task state ora- 解析 ant sql min struct ont 34.choose two View the Exhibit and examine the structure of the PRODUCT_INFORMATION and INVENTO

【Oracle 12c】CUUG OCP認證071考試原題解析35

date sel and ted rom The employ ssi employees 35.choose the best answer View the Exhibit and examine the description of the EMPLOYEES tab

【12c OCP】CUUG OCP認證071考試原題解析36

last iss bit 返回 cau ann following price tom 36.choose the best answer View the Exhibits and examine the structures of the PRODUCTS, SALES

認證授權方案之JwtBearer認證

# 1.前言 **回顧**:[認證方案之初步認識JWT](https://www.cnblogs.com/i3yuan/p/11519431.html) 在現代Web應用程式中,即分為前端與後端兩大部分。當前前後端的趨勢日益劇增,前端裝置(手機、平板、電腦、及其他裝置)層出不窮。因此,為了方便滿足前端裝置

割點

enume urn 目前 pointer passing cit create ins util 註:本文翻譯自http://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/。如有翻譯

Java中的會話管理——HttpServlet,Cookies,URL Rewriting

資源 gets where pre 點擊 相關 商品 另一個 格林尼治 參考谷歌翻譯,關鍵字直接使用英文,原文地址:http://www.journaldev.com/1907/java-session-management-servlet-httpsession-url-