微服務安全(一)
- 2021 年 10 月 7 日
- 筆記
- Spring Cloud
前言
在微服務架構中一個應用通常會被拆分成一系列的微服務,這些微服務需要對訪問者進行身份認證及鑒權,而此時進行應用安全管理,針對的不僅僅是用戶請求,還包含其他微服務的調用。這時候安全管理由原來單一的「用戶-服務」場景,變成了「用戶-服務」「服務-服務」的多種場景。而且對於微服務架構而言,動輒就要面對數十個乃至上百個微服務之間的調用,那麼該如何為這些調用提供高效安全的身份認證及鑒權呢?而且,當這些微服務面對外部用戶請求時,如何提供細粒度的安全管控方案也是一個極為重要的問題。
為了解決微服務架構的安全問題,主要有如下四種解決方案:
- 單點登錄(SSO)方案
- 分佈式會話(Session)方案
- 客戶端令牌(Token)方案
- 客戶端令牌與API網關結合
需要注意的是,這幾種解決方案彼此之間並不是毫無關係,反而是關聯緊密層層遞進,為開發者如何解決微服務架構下的安全問題提供了重要的指導作用。
單點登錄(SSO)方案
簡單來說,單點登錄就是在多個系統中,用戶只需一次登錄,其他各個系統均可感知該用戶已經登錄。
一般的單點登錄方案實現思路如下:
- 用戶登錄時,驗證用戶的賬戶和密碼
- 生成一個Token保存在數據庫中,將Token寫到Cookie中
- 將用戶數據保存在Session中
- 請求時都會帶上Cookie,檢查有沒有登錄,如果已經登錄則放行
單點登錄方案是最常見的解決方案,但需要每個與用戶交互的服務都必須與認證服務進行通信,這不但會造成重複,也會產生大量瑣碎的網絡流量;
分佈式會話(Session)方案
上面又說道,單點登錄功能主要是用Session保存用戶信息來實現的。但是多系統可能有多個Tomcat,而Session是依賴當前系統的Tomcat,所以系統A的Session和系統B的Session是不共享的。為了解決Session不共享問題,又產生了幾種解決方案:
- Tomcat集群Session全局複製(集群內每個Tomcat的Session完全同步)
- 根據請求的IP進行Hash映射到對應的機器上(這就相當於請求的IP一直會訪問同一個服務器)
- 把Session數據放在Redis中
前兩種方案分別存在影響性能以及單系統故障數據丟失的問題,因此一般情況下會建議採用第三種方案,這也就是分佈式會話方案。
通過將用戶會話信息存儲在共享存儲(如Redis)中,並使用用戶會話的ID作為key來實現分佈式哈希映射。當用戶訪問微服務時,會話數據就可以從共享存儲中獲取。該解決方案在高可用和擴展方面都很好,但是由於會話信息保存在共享存儲中,所以需要一定的保護機制保護數據安全,因此在具體的實現中會具有比較高的複雜度。
客戶端令牌(Token)方案
令牌由客戶端生成,並由認證服務器簽名。在令牌中會包含足夠的信息,客戶端在請求時會將令牌附加在請求上,從而為各個微服務提供用戶身份數據。此方案解決了分佈式會話方案的安全性問題,但如何及時註銷用戶認證信息則是一個大問題,雖然可以使用短期令牌並頻繁地與認證服務器進行校驗,但並不可以徹底解決。JWT(JSON Web Tokens)是非常出名的客戶端令牌解決方案,它足夠簡單,並且對各種環境支持程度也比較高。
客戶端令牌與API網關結合
通過在微服務架構中實施API網關,可以將原始的客戶端令牌轉換為內部會話令牌。一方面可以有效地隱藏微服務,另一方面通過API網關的統一入口可以實現令牌的註銷處理。
總結
隨着近幾年雲服務應用的發展,基於令牌(Token)的認證使用範圍也越來越廣。對於基於令牌認證通常包含下面幾層含義:
- 令牌是認證用戶信息的集合,而不僅僅是一個無意義的ID;
- 在令牌中已經包含足夠多的信息,驗證令牌就可以完成用戶身份的校驗,從而減輕了因為用戶驗證需要檢索數據庫的壓力,提升了系統性能;
- 因為令牌是需要服務器進行簽名發放的,所以如果令牌通過解碼認證,我們就可以認為該令牌所包含的信息是合法有效的;
- 服務器會通過HTTP頭部中的Authorization獲取令牌信息並進行檢查,並不需要在服務器端存儲任何信息;
- 通過服務器對令牌的檢查機制,可以將基於令牌的認證使用在基於瀏覽器的客戶端和移動設備的App或是第三方應用上;
- 可以支持跨程序調用。基於Cookie是不允許垮域訪問的,而令牌則不存在這個問題
綜上所述,基於令牌的認證由於會包含認證用戶的相關信息,因此可以通過驗證令牌來完成用戶身份的校驗,完全不同於之前基於會話的認證。因此,基於令牌的這個優點,像微信、支付寶、微博及GitHub等,都推出了基於令牌的認證服務,用於訪問所開放的API及單點登錄。
參考資料:
《Spring Cloud微服務架構開發實戰》
//zhuanlan.zhihu.com/p/66037342