Rest API的認證模式

Rest API的認證模式

微服務系統中,很多團隊採用了API驅動設計開發,服務之間的調用都通過API來實現的。爲了統一管理API,一般都會在前面部署一個API Gateway,然後由API Gateway對API的調用者進行權限認證。 常見的認證方式有下面幾種:

  • AppKey
  • AppKey + Secret
  • JWT
  • OAuth

下面我們逐一來介紹這些App的認證方式,以及對應的使用場景.

AppKey

AppKey 是比較悠久,也是比較簡單但是蠻有效的一種方式方法。當Application申請訪問API後,API Gateway會爲這個Application生成一個AppKey,一般是UUID等隨機無意義的字符串。當Application調用API的時候,需要在Http Header或者是Query裏面帶上這個AppKey, 然後API Gateway進行校驗,驗證無誤後方可訪問到具體的API。 比如

GET http://api.example.com/users?AppKey=1234567890abcdef

或者是在header裏面:

GET http://api.example.com/users
x-app-key=1234567890abcdef

不建議放在Query裏面,這樣很容易就被爆出來,因爲即使是HTTPS連接,URL也是不會加密的。同時建議用RFC7235關於HTTP認證部分的標準,以Authorization header的方式進行連接:

GET http://api.example.com/users?AppKey=1234567890abcdef
Authorization: AppKey 1234567890abcdef

小結:AppKey簡單明瞭,帶着key直接就可以走了!如果只是爲了能識別API的調用者,同時進行一些常規的API Gateway邏輯,AppKey也就夠了。其實微軟Azure API Management裏面的subscription 就是直接用AppKey作爲Header進行訪問的。

AppKey + Secret

我們知道Hash算法可以能夠完成密碼學四大目標之一的完整性檢驗,但是不能避免消息被篡改:比如有人將內容以及Hash一起給改掉。爲了避免消息被篡改,偉大的前人設計出消息驗證碼(Message Authentication Code), 在計算hash的時候,同時在裏面加入密鑰,得出基於Hash的消息驗證碼,常見的有HMAC (Hash-based Message Authentication Code).

現在我們要介紹的這種API的認證方式同時帶上AppKey以及消息驗證碼的。當Application申請訪問API後,API Gateway會爲這個Application生成一對Key, 一個叫AppKey,另一個叫App Secret。 API Gateway保存這對Key/Secret. 當Application發起請求時,首先是在HTTP 的header帶上這個AppKey,然後按照API Gateway的要求,對請求的HTTP Method, URL, body, header等消息進行串起來進行HMAC運算,並作爲HTTP Header - Authorization 發送,最終發給服務器的內容大致如下:

POST http://api.example.com/users
Authorization: AppKey 1234567890abcdef
X-Ca-Signature: HMAC(HTTP Method+Headers+Body)

Body content

當API Gateway收到這個請求之後,它會取出這個AppKey對應的AppSecret,然後以相同的算法對請求的內容進行HMAC運算,將得出的摘要跟發過來的摘要比較。這裏的摘要也有些地方叫 簽名。

小結:這種方式雖然稍微複雜了點,但同時把身份確認以及消息不被篡改的要求都滿足了。阿里雲API Gateway的subscription就是採用這種方式。

JWT

如果AppKey泄露或者被截取,竊取方在Application發現AppKey泄露之前,是可以用Application的不受限地進行API的調用。那怎樣才能最低程度地減少AppKey丟失之後的風險呢? 比如有效期縮短?

Json Web Token(縮寫JWT) 是目前比較流行的跨域身份認證解決方案。以令牌的方式進行溝通,而令牌自身帶着身份信息,並且具有時效性,過期無效。所以我們可以採用JWT來減少AppKey丟失之後的風險。

一個JWT包括3個部分:頭部(算法以及類型),Payload(具體的內容,主要是有效時間,名字等) 以及簽名。格式爲 aaaa.bbbbb.cccc. 每一部分的內容都用Base64編碼進行表示。

在這裏插入圖片描述

  • 首先Application在API Gateway註冊的時候,API Gateway會返回一對ID/Secret。
  • 在Application調用API之前,先帶上ID、Secret去調用API Gateway的Token接口,API Gateway 返回令牌
  • Application 把token放在Authorization header裏面,去請求API
  • API Gateway驗證JWT是否過期,簽名是否合法,以及Payload裏面的信息,如果合法就允許繼續訪問

如果Token別人截取了,那麼竊取方只能在token過期之前這個時間段內 假扮成Application去調用API。

小結:JWT會使得口令丟失的損失減低一些,同時payload裏面可以帶更多的有用的信息(當然標準規範裏面的payload也沒有多少可定製的字段),可以進行一些相應的權限或者業務操作。

OAuth

OAuth是一個可以爲第三方應用訪問用戶資源的安全框架。OAuth有4種不同的認證授權:

  • 授權碼模式 - Authorization Code
  • 客戶端憑據 - Client Credentials
  • 密碼模式 - Password
  • 隱式授權 - Implicit

授權碼模式跟隱式授權模式都是在有用戶的場景下使用 (隱式授權模式沒有授權碼,而是直接獲得access token),而密碼模式則是直接要用戶輸入用戶名密碼的,一般都不用。客戶端憑據 Client Credential 這種方式可以用來作爲API 的認證授權。

具體的操作流程跟JWT的方式下類似:

  • 首先Application在API Gateway註冊的時候,API Gateway會返回一對client Id / Secret。

  • 在Application調用API之前,先帶上client Id / Secret去調用API Gateway的Access Token接口,API Gateway 返回Access Token.

  • Application 把Access Token放在header裏面,Authorization: Bearer ACCESS_TOKEN 去請求API

  • API Gateway驗證Access Token是否過期,簽名是否合法,解開payload,檢查是否該令牌是否有權限訪問該資源,如果驗證通過 則允許繼續訪問

小結: API Gateway 的龍頭老大Google Apigee就是採用OAuth Client Credentials的方式進行Application的認證授權的,微軟Azure的API Management除了上面說的subscription的方式,也支持了AAD OAuth的方式,不過過程比較繁瑣。如果API Gateway除了需要身份認證之外,還需要進行權限的校驗,那麼以JWT作爲Access Token的OAuth是一種值得一試的方案。

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