如何構建安全的微服務應用

本文轉載於本人的微信公衆號中的文章,最新文章請關注公衆號。算法

目錄
1、前言
2、單體應用認證和鑑權
3、微服務認證和鑑權
一、面臨的問題
二、用戶身份認證
三、用戶狀態保持
四、實現單點登陸
五、用戶權限控制
六、微服務之間的認證與鑑權
七、第三方應用
4、總結後端

1、前言

咱們知道微服務技術或微服務架構是一把雙刃劍,其給咱們帶來了簡單、靈活的部署,聚焦、專一快速迭代,低耦合、高內聚、易擴展等優點;與此同時,也引入了更加複雜的問題。本文要着重闡述的如何在微服務架構中實現一個安全、高效的認證和鑑權方案。瀏覽器

2、單體應用認證和鑑權

咱們先回想下,在單體應用架構時咱們是怎麼對用戶進行認證和鑑別權限的?在單體架構下,每每會採用一個安全模塊來實現用戶認證和鑑權。緩存

  • 用戶認證
    當用戶登陸時,應用內的安全模塊對用戶身份進行驗證,驗證用戶身份合法後,爲該用戶生成一個會話(Session),併爲該Session關聯一個惟一的編號(Session Id)。Session是應用中的一小塊內存結構,其中保存了登陸用戶的信息,如User name, Role, Permission等。應用服務會將該Session的Session Id返回給客戶端,客戶端將Session Id以cookie或者URL重寫的方式記錄下來,並在後續請求中發送給應用,這樣應用在接收到客戶端訪問請求時可使用Session Id驗證用戶身份,不用每次請求時都輸入用戶名和密碼進行身份驗證。安全

  • 用戶鑑權
    在完成了用戶認證後,應用服務對用戶的每個請求攜帶過來的Session Id,進行對用戶權限判斷用戶,以此判斷用戶是否能執行該此請求,以實現操做鑑權。服務器

3、微服務認證和鑑權

3.1 面臨的問題

在微服務架構中,咱們知道微服務的粒度切分以業務邊界爲依據的。一個龐大的系統中,根據業務會劃分出不少的微服務。對每個微服務的訪問請求都須要進行認證和鑑權,微服務的認證和鑑權又面臨哪些問題?微信

  1. 微服務架構下的認證和鑑權涉及到場景更爲複雜,涉及到用戶訪問微服務應用,第三方應用訪問微服務應用,微服務之間相互訪問等多種場景,每種場景下的認證和鑑權方案都須要考慮到,如何來保證複雜場景下微服務的安全性?cookie

  2. 認證和鑑權邏輯,在微服務架構中放在什麼位置、哪一層,更爲合適?網絡

  3. 認證和鑑權成功後的信息如何存儲,如何維護調用方和服務方之間的認證關係?架構

  4. 微服務應用的權限粒度,如何作到API級別的控制?

3.2 技術方案

3.2.1 用戶身份認證

在微服務體系架構中,微服務應用是由多個相互獨立的微服務進程組成的,對每一個微服務的訪問都須要進行用戶認證。
微服務應用應遵循單一職責原理,即一個微服務只處理單一的業務邏輯。認證和鑑權的公共邏輯不該該放到微服務實現中。所以須要考慮一個抽象、公共的邏輯對用戶進行身份認證和鑑權服務。因爲在微服務架構中以API Gateway做爲對外提供服務的入口,所以能夠考慮在API Gateway處提供統一的用戶認證。具體就技術實現採用Zuul+Spring Security+OAuth2/JWT。

3.2.2 用戶狀態保持

在單體應用時,咱們是在服務器端採用Session和客戶端採用Cookie來保存用戶狀態,因爲在服務器是有狀態的,對服務器的水平擴展有影響。
咱們知道微服務架構的優點之一是微服務的水平擴展(Scalability)和彈性(Resiliency),因此微服務最好是無狀態的。所以建議採用Token來記錄用戶登陸狀態。
Token和Seesion主要的不一樣點是存儲的地方不一樣。
Session是集中存儲在服務器中的;而Token是用戶本身持有的,通常以Cookie的形式存儲在瀏覽器中。Token中保存了用戶的身份信息,每次請求都會發送給Gateway,所以能夠判斷訪問者的身份,並判斷其對請求的資源有沒有訪問權限。
Token用於代表用戶身份,其又以Cookie的形式存儲在瀏覽器中。爲了保障信息的安全,所以須要對其內容進行加密,避免被請求方或者第三者篡改。
JWT(Json Web Token)是一個定義Token格式的開放標準(RFC 7519),定義了Token的內容、加密方式並提供了各類語言的lib。
JWT Token的結構很是簡單,包括三部分:

  • Header
    頭部包含類型,爲固定值JWT。而後是JWT使用的Hash算法。

{
  "alg": "HS256",
  "typ": "JWT"
}
  • Payload
    包含發佈者,過時時間,用戶名等標準信息,也能夠添加用戶角色,用戶自定義的信息。

"sub": "1QAZWSX2", "name": "WY", "admin": true }
  • Signature
    Token頒發方的簽名,用於客戶端驗證Token頒發方的身份,也用於服務器防止Token被篡改。 
    簽名算法HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret),這三部分使用Base64編碼後組合在一塊兒,成爲最終返回給客戶端的Token,每部分之間採用」.「分隔。
    採用Token進行用戶認證,服務器端再也不保存用戶狀態,客戶端每次請求時都須要將Token發送到服務器端進行身份驗證。
    Token發送的方式rfc6750進行了規定,採用一個 Authorization: Bearer HHTP Header進行發送。

Authorization: Bearer 37mF-90B5f-86JqM

採用Token方式進行用戶認證的基本流程以下圖所示:

  1. 用戶輸入用戶名,密碼等驗證信息,向服務器發起登陸請求

  2. 服務器端驗證用戶登陸信息,生成JWT token

  3. 服務器端將Token返回給客戶端,客戶端保存在本地(通常以Cookie的方式保存)

  4. 客戶端向服務器端發送訪問請求,請求中攜帶以前頒發的Token

  5. 服務器端驗證Token,確認用戶的身份和對資源的訪問權限,並進行相應的處理(拒絕或者容許訪問)

  • 關於Token註銷
    因爲Token不存儲在服務端,由客戶端存儲。當用戶註銷時,Token的有效時間尚未到,仍是有效的。因此如何在用戶註銷登陸時讓Token註銷是一個要關注的點。通常有以下幾種方式:

  1. Token存儲在Cookie中,這樣客戶端註銷時,天然能夠清空掉

  2. 將Token存放到分佈式緩存中,每次校驗Token時區檢查下該Token是否已註銷。不過這樣也就失去了快速校驗Token的優勢。

  3. 多采用短時間令牌,好比令牌有效期是30分鐘,這樣能夠必定程度上下降註銷後 Token可用性的風險。

3.2.3 單點登陸

咱們看下維基百科中,對單點登陸的解釋。

單點登陸(英語:Single sign-on,縮寫爲 SSO),又譯爲單一簽入,一種對於許多相互關連,可是又是各自獨立的軟件系統,提供訪問控制的屬性。當擁有這項屬性時,當用戶登陸時,就能夠獲取全部系統的訪問權限,不用對每一個單一系統都逐一登陸。相同的,單一註銷(single sign-off)就是指,只須要單一的註銷動做,就能夠結束對於多個系統的訪問權限。

在微服務架構中,單點登陸能夠理解爲當用戶登陸成功後,就能夠訪問全部有權限訪問的微服務。API Gateway提供了客戶端訪問微服務的入口,Token實現了無狀態的用戶認證。結合這兩種技術,咱們就能夠爲微服務應用實現一個單點登陸方案。

微服務單點登陸流程下,用戶的認證和鑑權以下圖:

  • 用戶登陸

  1. 客戶端發送登陸請求到API Gateway

  2. API Gateway將登陸請求轉發到Security Service

  3. Security Service驗證用戶身份,並頒發Token

  • 用戶請求

  1. 客戶端請求發送到API Gateway

  2. API Gateway調用的Security Service對請求中的Token進行驗證,檢查用戶的身份

  3. 若是請求中沒有Token,Token過時或者Token驗證非法,則拒絕用戶請求。

  4. Security Service檢查用戶是否具備該操做權

  5. 若是用戶具備該操做權限,則把請求發送到後端的Business Service,不然拒絕用戶請求。

3.2.4 用戶權限控制

API Gateway處進行統一的權限控制
客戶端發送的HTTP請求中包含有請求的Resource及HTTP Method。若是系統遵循REST規範,以URI資源方式對訪問對象進行建模,則API Gateway能夠從請求中直接截取到訪問的資源及須要進行的操做,而後調用Security Service進行權限判斷,根據判斷結果決定用戶是否有權限對該資源進行操做,並轉發到後端的Business Service。這種實現方式API Gateway處統一處理認證和鑑權邏輯,各個微服務不須要考慮用戶認證和鑑權,只須要處理業務邏輯,簡化了各微服務的實現。

3.2.5 微服務之間的認證

微服務應用,除了來自用戶和第三方的訪問外,還有大量的微服務之間訪問。根據微服務應用的數據敏感程度的不一樣,對於微服務之間的相互訪問可能有不一樣的安全要求

  • 微服務間的相互訪問不進行認證和鑑權

  1. 依託網絡安全措施,來保障微服務間的通信安全

  2. 微服務提供的數據敏感程度不是很高
    在這種狀況下,一旦攻擊者侵入到內部網絡後沒有了保護措施。雖然微服務的數據敏感程度不高,可是攻擊行爲仍然給咱們帶來危害。

  • 服務間的訪問採用頒發訪問憑證進行安全控制
    微服務在使用的緯度上,咱們定義服務的調用方和服務的提供方。服務的提供方對調用方頒發訪問憑證,提供方對訪問嚴格控制;沒有訪問憑證的訪問,拒絕訪問;根據不一樣的訪問憑證類型,安全控制不一樣的訪問類型。

  • 服務間的訪問採用Service Account進行安全控制
    Istio-Auth提供強大的服務間認證和終端用戶認證,使用交互TLS,內置身份和證書管理。能夠升級服務網格中的未加密流量,併爲運維人員提供基於服務身份而不是網絡控制來執行策略的能力。Istio的將來版本將增長細粒度的訪問控制和審計,以使用各類訪問控制機制(包括基於屬性和角色的訪問控制以及受權鉤子)來控制和監視訪問您的服務,API或資源的人員。

Istio Security Architecture

Istio-Auth更多信息:https://istio.io/docs/concepts/security/mutual-tls/

3.2.6 第三方應用

OAuth2
OAuth2針對不一樣場景有不一樣的認證流程,一個典型的認證流程以下圖所示:

(圖片來源於網絡)

  1. 用戶向OAuth客戶端程序發起一個請求,OAuth客戶端程序在處理該請求時發現須要訪問用戶在資源服務器中的數據。

  2. 客戶端程序將用戶請求重定向到認證服務器,該請求中包含一個callback的URL。

  3. 認證服務器返回受權頁面,要求用戶對OAuth客戶端的資源請求進行受權。

  4. 用戶對該操做進行受權後,認證服務器將請求重定向到客戶端程序的callback url,將受權碼返回給客戶端程序。

  5. 客戶端程序將受權碼發送給認證服務器,請求token。

  6. 認證服務器驗證受權碼後將token頒發給客戶端程序。

  7. 客戶端程序採用頒發的token訪問資源,完成用戶請求。

POST /oauth/token HTTP/1.1
Host: authorization-server.com

grant_type=authorization_code
&code=xxxxxxxxxxx
&redirect_uri=https://example-app.com/redirect
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx

(引用:https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/)

4、總結

微服務架構下,認證和鑑權涉及到場景複雜,涉及到用戶訪問微服務應用,第三方應用訪問微服務應用,微服務之間相互訪問等多種場景。

  • 身份認證。確認「你是你」,獲取你的身份信息。

  • 權限驗證。確認「你能作某件事」。

權限建模時,每每會拆分紅功能權限和數據權限。上述的解決方案,從功能權限結合各類微服務應用場景下,抽象了身份認證和權限驗證模型。

-EOF-

相關文章
相關標籤/搜索