微服務架構下的安全認證與鑒權


從單體應用架構到分布式應用架構再到微服務架構,應用的安全訪問在不斷地經受考驗。為了適應架構的變化、需求的變化,身份認證與鑒權方案也在不斷地變革。面對數十個甚至上百個微服務之間的調用,如何保證高效安全的身份認證是個難題。面對外部的服務訪問,如何提供細粒度的鑒權方案也是個難題。

單體應用VS微服務

隨着微服務架構的興起,傳統的單體應用場景下的身份認證和鑒權面臨的挑戰越來越大。

在單體應用體系下,應用是一個整體,一般針對所有的請求都會進行權限校驗。請求一般會通過一個權限的攔截器進行權限的校驗,在登陸時將用戶信息緩存到Session中,后續訪問則從緩存中獲取用戶信息。

而在微服務架構下,一個應用會被拆分成若干個微應用,每個微應用都需要對訪問進行鑒權,每個微應用都需要明確當前訪問用戶以及其權限。尤其是當訪問來源不只是瀏覽器,還包括其他服務的調用時,單體應用架構下的鑒權方式就不是特別合適了。在微服務架構下,要考慮外部應用接入的場景、用戶-服務的鑒權、服務-服務的鑒權等多種鑒權場景。

David Borsos在倫敦的微服務大會上提出了四種方案:

1.單點登陸(SSO)。這種方案意味着,每個面向用戶的服務都必須與認證服務交互,會產生大量非常瑣碎的網絡流量和重復的工作,當動輒數十個微應用時,這種方案的弊端會更加明顯。

2.分布式Session方案。分布式會話方案的原理主要是講關於用戶認證的信息存儲在共享存儲中,且通常由用戶會話作為key來實現的簡單分布式哈希映射。當用戶訪問微服務時,用戶數據可以從共享存儲中獲取。在某些場景下,這種方案很不錯,用戶登陸狀態是不透明的。同時也是一個高可用且可擴展的解決方案。這種方案的缺點在於,共享存儲需要一定的保護機制,因此需要通過安全鏈接來訪問,這時解決方案的實現就通常具有相當高的復雜性了。

3.客戶端Token方案。令牌(Token)在客戶端生成,由身份驗證服務進行簽名,並且必須包含足夠的信息,以便可以在所有的微服務中建立用戶身份。令牌會附加到每個請求上,為微服務提供用戶身份驗證,這種解決方案的安全性相對較好,但是身份驗證的注銷是一個大問題,緩解這種情況的方法可以使用短期令牌和頻繁檢查認證服務等。對於客戶端令牌的編碼方案,Borsos更喜歡使用JSON Web Tokens(JWT),它足夠簡單,且庫支持程度也比較好。

4.客戶端Token與API網關結合。這個方案意味着所有的請求都會通過網關,從而有效地隱藏了微服務。在請求時,網關將原始用戶令牌轉換為內部會話ID令牌。在這種情況下,注銷就不是問題,因為網關可以在注銷時撤銷用戶的令牌。

微服務常見安全認證方案

微服務常見安全認證方案主要由三種:HTTP基本認證、基於Session的認證和基於Token的認證。

HTTP基本認證(HTTP Basic Authentication)

HTTP基本認證是HTTP1.0提出的一種認證機制,過程如下:

1.客戶端發送HTTP Request給服務器。

2.因為Request中並沒有包含Authorization Header,服務器就會返回一個401 Unauthozied給客戶端,並且在Response的Header的【WWW-Authenticate】屬性中添加信息。

3.客戶端把用戶名和密碼用BASE64加密后,放在Authorization Header中發送給服務器,認證成功。

4.服務器將Authorization Header中的用戶名和密碼取出,進行驗證,如果驗證通過,將根據請求,發送資源給客戶端。

基於Session的認證

基於Session的認證應該是最常用的一種認證機制了。用戶登陸認證成功后,將用戶相關數據存儲到Session中。單體應用架構中,默認Session會存儲在應用服務器中,並且將SessionID返回到客戶端中,存儲到瀏覽器的Cookie中;分布式架構中,Session存放於某個具體的應用服務器自然是無法滿足使用,簡單的可以通過Session復制或Session粘滯的方案來解決。

Session復制依賴於應用服務器,需要應用服務器有Session復制能力,不過現在大部分應用服務器如Tomcat、JBoss和WebSphere等都提供了這個能力。

除此之外,Session復制的一大缺陷在於,當節點數比較多時,大量的Session數據復制會占用較多的網絡資源。Session粘滯是通過負載均衡器,將統一用戶的請求都分發到固定的服務器節點上,這樣就保證了對某一個用戶而言,Session數據始終是正確的。不過這種方案依賴於負載均衡器,並且只能滿足水平擴展的集群場景,無法滿足應用分割后的分布式場景。

在微服務架構下,每個微服務拆分的粒度會很細,並且不只有用戶和微服務打交道,更多的還有微服務之間的調用。這個時候,上述兩個方案都無法滿足,就要求必須要將Session從應用服務器中剝離出來,存放在外部進行集中管理。可以是數據庫,也可以是分布式緩存,比如Memchached、Redis等。這正是David Boros建議的第二種方案:分布式Session方案。

基於Token的認證

隨着Restful API、微服務的興起,基於Token的認證現在已經越來越普遍。Token和SessionID不同,並非只是一個key。Token一般會包含用戶的相關信息,通過驗證Token就可以完成身份校驗。像Twitter、微信、QQ、Github等公有服務的API都是基於這種方式進行認證的,一些開發框架如OpenStack、Kubernates內部API調用也是基於Token認證。基於Token認證的一個典型流程如下:

1.用戶輸入登陸信息(或者調用Token接口,傳入用戶信息),發送到身份認證服務進行認證(身份認證服務可以和服務端在一起,也可以分離,看微服務拆分情況)。

2.身份認證服務驗證登陸信息是否正確,返回Token(一般Token中會包含用戶基礎信息、權限范圍、有效時間等信息),客戶端存儲Token,可以存儲在Session或者數據庫中。

3.用戶將Token放在HTTP請求頭中,發起相關API調用。

4.被調用的微服務,驗證Token權限。

5.服務端返回相關資源和數據。

基於Token認證的好處

1.服務端無狀態。Token機制在服務端不需要存儲Session信息,因為Token自身包含了所有用戶的相關信息。

2.性能較好。因為在驗證Token的時候不用再去訪問數據庫或者遠程服務進行權限校驗,自然可以提升不少性能。

3.支持移動設備。

4.支持跨程序調用。Cookie是不允許跨域訪問的,而Token則不會存在這個問題。

 

轉自:https://mp.weixin.qq.com/s/x0CZpovseOuofTA_lw0HvA

"我從來沒有被誰捧在手心里真正地愛過,每一次我都好像在克制自己,不要發脾氣,要懂事,可是只有我自己知道,我有多么難過,多么心累。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM