web-security第一期:簡談 OAuth2.0 協議

聲名:此文有參考 鏈接  (鳴謝!)

目錄

1.簡述OAuth2.0

名詞解釋

2.令牌(token)與密碼

3.Access Token & Refresh Token

Access Token

Refresh Token

4.RFC 6749 文件

4.授權模式

4.1.簡化模式

4.2.授權碼模式(官方推薦模式)

4.3.密碼模式

4.4.客戶端模式


1.簡述OAuth2.0

OAuth 2.0 是目前最流行的授權機制,用來授權第三方應用,獲取用戶數據。

名詞解釋

  • 第三方應用程序(Third-party application): 又稱之爲客戶端(client),比如上節中提到的設備(PC、Android、iPhone、TV、Watch),我們會在這些設備中安裝我們自己研發的 APP。又比如我們的產品想要使用 QQ、微信等第三方登錄。對我們的產品來說,QQ、微信登錄是第三方登錄系統。我們又需要第三方登錄系統的資源(頭像、暱稱等)。對於 QQ、微信等系統我們又是第三方應用程序。
  • HTTP 服務提供商(HTTP service): 我們的雲筆記產品以及 QQ、微信等都可以稱之爲“服務提供商”。
  • 資源所有者(Resource Owner): 又稱之爲用戶(user)。
  • 用戶代理(User Agent): 比如瀏覽器,代替用戶去訪問這些資源。
  • 認證服務器(Authorization server): 即服務提供商專門用來處理認證的服務器,簡單點說就是登錄功能(驗證用戶的賬號密碼是否正確以及分配相應的權限)
  • 資源服務器(Resource server): 即服務提供商存放用戶生成的資源的服務器。它與認證服務器,可以是同一臺服務器,也可以是不同的服務器。簡單點說就是資源的訪問入口,比如上節中提到的“雲筆記服務”和“雲相冊服務”都可以稱之爲資源服務器。

資源擁有者告訴服務提供方同意授權第三方應用進入系統獲取這些數據。系統從而產生一個短期的進入令牌(token),用來代替密碼,供第三方應用使用

2.令牌(token)與密碼

令牌(token)與密碼都可以作爲訪問資源服務器的憑證,但有下面三點不同:

  • 令牌可以規定授權範圍(scope),比如對某些數據只有只讀的權限。而密碼一般是完整權限
  • 令牌是有有效期限制的,逾期無效(因爲令牌本身也是很重要的憑證),而持有者也無法對其進行更改,密碼則是長期有效並且可修改
  • 資源所有者可以隨時決定令牌有效與否,對於網絡服務來說,只讀令牌就比讀寫令牌更安全

3.Access Token & Refresh Token

Access Token

Access Token 是客戶端訪問資源服務器的令牌。擁有這個令牌代表着得到用戶的授權。然而,這個授權應該是 臨時 的,有一定有效期。這是因爲,Access Token 在使用的過程中 可能會泄露。給 Access Token 限定一個 較短的有效期 可以降低因 Access Token 泄露而帶來的風險。

然而引入了有效期之後,客戶端使用起來就不那麼方便了。每當 Access Token 過期,客戶端就必須重新向用戶索要授權。這樣用戶可能每隔幾天,甚至每天都需要進行授權操作。這是一件非常影響用戶體驗的事情。希望有一種方法,可以避免這種情況。

於是 oAuth2.0 引入了 Refresh Token 機制

Refresh Token

Refresh Token 的作用是用來刷新 Access Token。認證服務器提供一個刷新接口,例如:

http://www.funtl.com/refresh?refresh_token=&client_id=

傳入 refresh_token 和 client_id,認證服務器驗證通過後,返回一個新的 Access Token。爲了安全,oAuth2.0 引入了兩個措施:

  • oAuth2.0 要求,Refresh Token 一定是保存在客戶端的服務器上 ,而絕不能存放在狹義的客戶端(例如 App、PC 端軟件)上。調用 refresh 接口的時候,一定是從服務器到服務器的訪問。
  • oAuth2.0 引入了 client_secret 機制。即每一個 client_id 都對應一個 client_secret。這個 client_secret 會在客戶端申請 client_id 時,隨 client_id 一起分配給客戶端。客戶端必須把 client_secret 妥善保管在服務器上,決不能泄露。刷新 Access Token 時,需要驗證這個 client_secret

實際上的刷新接口類似於:

http://www.funtl.com/refresh?refresh_token=&client_id=&client_secret=

以上就是 Refresh Token 機制。Refresh Token 的有效期非常長,會在用戶授權時,隨 Access Token 一起重定向到回調 URL,傳遞給客戶端。

4.RFC 6749 文件

OAuth 2.0 的標準是 RFC 6749 文件。該文件先解釋了 OAuth 是什麼。

OAuth 引入了一個授權層,用來分離兩種不同的角色:客戶端和資源所有者。......資源所有者同意以後,資源服務器可以向客戶端頒發令牌。客戶端通過令牌,去請求數據。

OAuth 2.0 規定了四種獲得令牌的流程。你可以選擇最適合自己的那一種,向第三方應用頒發令牌。下面就是這四種授權方式。

  • 授權碼(authorization-code)
  • 隱藏式(implicit)
  • 密碼式(password):
  • 客戶端憑證(client credentials)

注意,不管哪一種授權方式,第三方應用申請令牌之前,都必須先到系統備案,說明自己的身份,然後會拿到兩個身份識別碼:客戶端 ID(client ID)和客戶端密鑰(client secret)。這是爲了防止令牌被濫用,沒有備案過的第三方應用,是不會拿到令牌的。

4.授權模式

4.1.簡化模式

簡化模式適用於純靜態頁面應用。所謂純靜態頁面應用,也就是應用沒有在服務器上執行代碼的權限(通常是把代碼託管在別人的服務器上),只有前端 JS 代碼的控制權。

這種場景下,應用是沒有持久化存儲的能力的。因此,按照 oAuth2.0 的規定,這種應用是拿不到 Refresh Token 的。其整個授權流程如下:

 

該模式下,access_token 容易泄露且不可刷新

4.2.授權碼模式(官方推薦模式)

授權碼模式適用於有自己的服務器的應用,它是一個一次性的臨時憑證,用來換取 access_token 和 refresh_token。認證服務器提供了一個類似這樣的接口:

https://www.funtl.com/exchange?code=&client_id=&client_secret=

需要傳入 codeclient_id 以及 client_secret。驗證通過後,返回 access_token 和 refresh_token。一旦換取成功,code 立即作廢,不能再使用第二次。流程圖如下:

這個 code 的作用是保護 token 的安全性。上一節說到,簡單模式下,token 是不安全的。這是因爲在第 4 步當中直接把 token 返回給應用。而這一步容易被攔截、竊聽。引入了 code 之後,即使攻擊者能夠竊取到 code,但是由於他無法獲得應用保存在服務器的 client_secret,因此也無法通過 code 換取 token。而第 5 步,爲什麼不容易被攔截、竊聽呢?這是因爲,首先,這是一個從服務器到服務器的訪問,黑客比較難捕捉到;其次,這個請求通常要求是 https 的實現。即使能竊聽到數據包也無法解析出內容。

有了這個 code,token 的安全性大大提高。因此,oAuth2.0 鼓勵使用這種方式進行授權,而簡單模式則是在不得已情況下才會使用。

4.3.密碼模式

密碼模式中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向 "服務商提供商" 索要授權。在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分。

一個典型的例子是同一個企業內部的不同產品要使用本企業的 oAuth2.0 體系。在有些情況下,產品希望能夠定製化授權頁面。由於是同個企業,不需要向用戶展示“xxx將獲取以下權限”等字樣並詢問用戶的授權意向,而只需進行用戶的身份認證即可。這個時候,由具體的產品團隊開發定製化的授權界面,接收用戶輸入賬號密碼,並直接傳遞給鑑權服務器進行授權即可。

有一點需要特別注意的是,在第 2 步中,認證服務器需要對客戶端的身份進行驗證,確保是受信任的客戶端。

4.4.客戶端模式

如果信任關係再進一步,或者調用者是一個後端的模塊,沒有用戶界面的時候,可以使用客戶端模式。鑑權服務器直接對客戶端進行身份驗證,驗證通過後,返回 token。

 

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