微服務訪問安全設計方案實踐

天府雲創發表於2019-01-03

我們首先從傳統單體應用架構下的訪問安全設計說起,然後分析現代微服務架構下,訪問安全涉及的原則,接著討論目前常用的幾種微服務架構下的訪問安全設計方案。最後,詳析Spring Cloud微服務架構下如何解決訪問安全的問題。

1.傳統單體應用的訪問安全設計

這裡寫圖片描述

上面的示意圖展示了單體應用的訪問邏輯。使用者通過客戶端發出http或者https請求,經過負載均衡後,單體應用收到請求。接著經過auth層,進行身份驗證和許可權批准,這裡,一般會有跟後端資料庫的互動。通過後,將請求分發到對應的功能邏輯層中去。完成相關操作後,返回結果給客戶端。

1.1傳統單體應用的訪問安全設計——原則

在這裡插入圖片描述
從以上分析可以看到,傳統單體應用的訪問安全設計原則為:

第一,每次的使用者請求都需要驗證是否安全,這裡可以分兩種情況:

一種是沒有session的請求,需要經過幾個步驟完成session化。一般為驗證當前使用者的credential,獲取當前使用者的identity,這兩步都需要訪問資料庫等持久化物件來完成,最後一步是為當前可用建立session,返回給客戶端後,啟用該session。

另一種是有session的請求,只需驗證請求中當前session的有效性,即可繼續請求。

第二,使用者的操作請求都在後端單個程式中執行完成,完全依賴後端呼叫方法的可靠性。一旦出錯,應用是無法再次重複請求。

1.2 傳統單體應用的訪問安全設計——優勢和注意點

在這裡插入圖片描述

傳統單體應用由於設計相對簡單單一,暴露給外界的入口相對較少,從而具有被攻擊並造成危害性的可能小的優勢。

也正是由於單體應用簡單單一的特點,需要注意相關問題:

應用後端儲存了所有的credential等敏感資訊
一旦入侵了對這個應用的請求,就有可能拿到所有的儲存在後端的資訊
應用的每次操作一般都需要和資料庫進行互動,造成資料庫負載變高

2.微服務架構下,訪問安全設計原則

在這裡插入圖片描述

來看下這張典型的微服務設計架構圖,如圖所示,有以下幾點特徵:

  • 每個服務只有許可權去操作自己負責的那部分功能。
  • 使用者請求的身份驗證和許可權批准都由獨立的gateway服務來保障
  • 對外服務的LB層無法直接與提供業務服務的應用層進行訪問

在這裡插入圖片描述

從上面的特徵分析來看,想要給出一份訪問安全設計的原則說明,就要看看微服務架構下,訪問安全有哪些痛點,以下羅列了幾點:

  • 單點登入,即在微服務這種多獨立服務的架構下,實現使用者只需要登入一次就能訪問所有相互信任的應用系統
  • 微服務架構下的應用一般都是無狀態的,導致使用者的請求每次都需要鑑權,可能引發Auth服務的效能瓶頸
  • 微服務架構下,每個元件都管理著各自的功能許可權,這種細粒度的鑑權機制需要事先良好的規劃
  • 微服務架構下,需要考慮到那些非瀏覽器端的客戶請求,是否具有良好的可操作性

根據實際情況,還有一些其他痛點,這裡不再一一贅述,而這些痛點,就形成了我們在為微服務架構設計訪問安全的原則。

3.微服務架構下,常用的訪問安全設計方案

  • HTTP Basic Authentication + Independent Auth DB
  • HTTP Basic Authentication + Central Auth DB
  • API Tokens
  • SAML

這裡列出4種,首先簡單介紹下,然後一一敘述。

第一種,使用HTTP Basic Auth協議,加上獨立的Auth資料庫。
第二種,也是使用HTTP Basic Auth協議,跟第一種不同的是,使用集中式的Auth資料庫
第三種,API Tokens協議,這種大家應該比較熟悉,很多公有服務(比如Github、Twitter等)的API都是用這種方式。
第四種,SAML,即Security Assertion Markup Language,翻譯過來,是『安全宣告標記語言』,它是基於XML的一種協議,企業內使用得較多。

下面一一做介紹。

3.1 微服務常用訪問安全設計方案——Basic Auth + Independent Auth DB

在這裡插入圖片描述

一種,如上示意圖所示,使用Basic Auth協議,配合每個服務自己都擁有儲存Credential敏感資料的資料庫(或者其他持久化倉庫)。

簡單介紹下Basic Auth協議,它是在使用者的請求中新增一個Authorization訊息頭,這個訊息頭的值是一個固定格式:Basic base64encode(username+“:”+password)

完整的訊息頭列子為:Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Basic Auth協議基本上被所有流行的網頁瀏覽器都支援。

這種方案的特點:

  • 每個提供功能的服務都擁有自己獨立的鑑權和授權機制
  • 每個提供功能的服務都擁有自己獨立的資料庫,來儲存敏感資訊
  • 每次使用者請求都需要攜帶使用者的credential來完成操作

小結下使用這種方案的好處:

  • 微服務的應用可以實現100%無狀態化
  • 基於Basic Auth開發簡單

同時,小結下使用這種方案需要注意的地方:

由於每個服務都有自己儲存credential的機制,需要事先為每個服務設計好如何儲存和查詢使用者的Credential由於每次使用者請求都會攜帶使用者的Credential,需要事先設計好如何管理鑑權機制。

3.2微服務常用訪問安全設計方案——Basic Auth + Central Auth DB

在這裡插入圖片描述

二種,如上示意圖所示,使用Basic Auth協議,與第一種方案相比,每個服務共用有同一個Auth DB。

第二種方案的特點和第一種很相似:

  • 每個提供功能的服務都擁有自己獨立的鑑權和授權機制
  • 每個提供功能的服務共用同一個DB,來儲存Credential等敏感資訊
  • 每次使用者請求都需要攜帶使用者的credential來完成操作

小結下使用第二種方案的好處:

除了擁有第一種方案相似的好處外,由於共用了同一個持久化倉庫來管理使用者資訊,簡化了原來獨立管理的機制

同時,小結下使用這種方案需要注意的地方:

  • 中心化Auth DB會被每次使用者請求來訪問連線,可能引發AuthDB效能瓶頸
  • 需要在每個服務中實現對共有Auth DB查詢使用者資訊的邏輯

3.3微服務常用訪問安全設計方案——API Tokens

在這裡插入圖片描述
第三種,如上示意圖所示,使用Token Based協議來對使用者請求進行操作鑑權。

簡單介紹下最基本的Token Based的互動方式:

  • 使用者使用包含使用者名稱和密碼的credential從客戶端發起資源請求
  • 後端接受請求,通過授權中心,生產有效token字串,返回給客戶端
  • 客戶端獲得token後,再次發出資源請求
  • 後端接受帶token的請求,通過授權中心,獲取相關資源,返回給客戶端
    業界常用的OAuth就是基於Token Based這套邏輯,實現的網際網路級的鑑權機制。

第三種方案的特點明顯:

使用token來進行鑑權,替換使用者本身的使用者名稱和密碼,提高了互動安全性每次使用者請求需要攜帶有效token,與Auth服務進行互動驗證

小結下使用第三種方案的好處:

由於使用了token來鑑權,業務服務不會看到使用者的敏感資訊

同時,小結下使用這種方案需要注意的地方:

Auth服務可能需要處理大量的生產token的操作

3.4微服務常用訪問安全設計方案——SAML

在這裡插入圖片描述

第四種,如上示意圖所示,使用SAML協議來對使用者請求進行操作鑑權。它是一個基於XML的標準,用於在不同的安全域(security domain)之間交換認證和授權資料。在SAML標準定義了身份提供者(identity provider)和服務提供者(service provider),這兩者構成了前面所說的不同的安全域。

以上圖Google提供的Apps SSO的機制,簡單介紹下SAML鑑權的互動方式:

  • 使用者請求訪問自建的google application
  • 當前application 生成一個 SAML 身份驗證請求。SAML 請求將進行編碼並嵌入到SSO 服務的網址中。
  • 當前application將重定向傳送到使用者的瀏覽器。重定向網址包含應向SSO 服務提交的編碼 SAML 身份驗證請求。
  • SSO(統一認證中心或叫Identity Provider)解碼 SAML 請求,並提取當前application的 ACS(宣告客戶服務)網址以及使用者的目標網址(RelayState 引數)。然後,統一認證中心對使用者進行身份驗證。
  • 統一認證中心生成一個 SAML 響應,其中包含經過驗證的使用者的使用者名稱。按照 SAML 2.0 規範,此響應將使用統一認證中心的 DSA/RSA 公鑰和私鑰進行數字簽名。
  • 統一認證中心對 SAML 響應和 RelayState 引數進行編碼,並將該資訊返回到使用者的瀏覽器。統一認證中心提供了一種機制,以便瀏覽器可以將該資訊轉發到當前application ACS。
  • 當前application使用統一認證中心的公鑰驗證 SAML 響應。如果成功驗證該響應,ACS 則會將使用者重定向到目標網址。
  • 使用者將重定向到目標網址並登入到當前application。

目前SAML在業界也有相當的使用度,包括IBM Weblogic等產品。

第四種方案的特點有:

由Identity Provider提供可信的簽名宣告服務的訪問安全由可信的Identity Provider提供

小結下使用第四種方案的好處:標準的可信訪問模型

同時,小結下使用這種方案需要注意的地方:

基於XML協議,傳輸相對複雜對非瀏覽器客戶端適配不方便。

4.Spring Cloud Security解決方案

Spring Cloud Security特點有:

  • 基於OAuth2 和OpenID協議的可配置的SSO登入機制
  • 基於tokens保障資源訪問安全
  • 引入UAA鑑權服務,UAA是一個Web服務,用於管理賬戶、Oauth2客戶端和使用者用於鑑權的問題令牌(Issue Token)。UAA實現了Oauth2授權框架和基於JWT(JSON web tokens)的問題令牌。

在這裡插入圖片描述

下面簡單介紹下UAA,事實上,它是由CloudFoundry發起的,也是CloudFoundry平臺的身份管理服務(https://docs.cloudfoundry.org…)。

主要功能是基於OAuth2,當使用者訪問客戶端應用時,生成併發放token給目標客戶端。

UAA認證服務包含如下幾個方面的內容:

  • 認證物件。如使用者、客戶端以及目標資源伺服器
  • 認證型別。主要有授權碼模式、密碼模式以及客戶端模式
  • 認證範圍,即認證許可權,並作為一個命名的引數附加到AccessToken上。

接下來,結合例項,一起來看下UAA在Spring Cloud中的實踐。

在這裡插入圖片描述

如圖所示,這是一個簡單的基於Spring Cloud微服務架構的例子,它的主要元件有:

  • Eureka元件提供服務發現功能
  • 獨立的Config元件提供類似配置中心的服務,持久化層可以是檔案系統,也可是git repository
  • Auth元件提供基於UAA的鑑權服務
  • Account元件儲存使用者的業務資訊 其他元件不一一介紹了

這裡主要講Auth元件和Account元件是如何基於UAA服務進行認證和授權。

在這裡插入圖片描述

一為Auth元件業務程式碼中定義了不同客戶端的認證型別和認證範圍,其中:

瀏覽器端的認證型別是password,認證範圍是uiaccount元件端的認證型別是client_credentials,認證範圍是server

圖二為config元件(配置中心)定義的請求路由的規則,其中:

使用/uaa/**來轉發基於uaa的認證請求至auth元件
使用/accouts/**來轉發請求至account元件,並標記serviceId為account-service,與圖一中的withClient對應。

在這裡插入圖片描述

一為瀏覽器開啟應用入口後,輸入使用者名稱和密碼後,發出的認證請求:

認證url為/uaa/oauth/token,這是uaa模式下標準的請求獲取token的url表單中包含了欄位scope(認證範圍)和欄位password(認證型別)

圖二為圖一發出認證請求的返回結果:

Access_token為有效認證token,將來被其他請求使用

圖三為發出獲取當前使用者的資訊的請求:

在請求裡的Authorization的值為圖二中獲得的access_token

在這裡插入圖片描述

圖一為Account元件在Config元件(配置中心)定義的OAuth2協議下獲取token的方式,這裡定義了:

clientID和clientSecret
accessTokenUrl,這裡指定了auth元件的uaa獲取token的url
grant-type,即認證型別,這裡指定為client_credentials
scope,這裡指定了server,說明是這個認證請求只適用在各微服務之間的訪問。

圖二為Accout元件業務程式碼中定義了需要使用Auth元件進行事先鑑權的方法:

使用@PreAuthorize
annotation中可以指定認證範圍的具體條件,這裡是限定了server或者是demo賬戶,才有許可權發起認證。

在這裡插入圖片描述

最後小結下Spring Cloud Security的特點:

  • 基於UAA,使用OAuth2協議。不會暴露使用者的敏感資訊
  • 基於認證型別和認證範圍,實現細粒度的鑑權機制
  • 非瀏覽器客戶端下良好的操作性

5.Q&A

問題:Basic Auth + Central Auth DB這種方式中,每個服務有自己的鑑權DB,這塊只是一個緩衝嗎?如果中途通過別的方式修改了中心DB的資料,而緩衝又沒過期,這個時候有什麼解決方案嗎?答:不是緩衝,這裡的Central Auth DB是指各個微服務共用一個資料庫。

問題:微服務架構需要服務路由和服務註冊麼?跟esb的區別在哪裡?答:服務路由元件和服務註冊元件和是相對必要的,他們保證了使用者請求能發到正確的微服務中去。ESB企業服務匯流排是相對比較重的元件,而不是像微服務元件一樣只負責單個業務。

問題:在微服務中,對於資料許可權的粒度,是可以集中在在gateway中進行還是由每個微服務自己獨立配置?答:推薦由那個專門負載許可權的微服務元件來配置。

問題:您好,辛苦了,請問現在有類似SAML協議,但是不基於XML,而是基於JSON或者其他簡化格式的協議嗎?答:目前據我所知沒有基於JSON的SAML協議。有個叫JWT(JSON web token)的協議,它是完全基於JSON的,Spring Cloud架構中也使用了JWT。

問題:對於這個架構,服務劃分的粒度有沒有什麼好的建議?另外登入憑證儲存在客戶端如何解決報文被攔截的安全漏洞?答:服務劃分需要按具體業務來說,一般來說,一個業務實體作為一個微服務。使用https可以一定程度上提高安全性。

問題:spring cloud security可以解決token重放攻擊麼?答:token重放攻擊不是特別瞭解,可能是資料弱一致性導致的,建議設計儘可能短的過期時間。

問題:我們公司現在在設計DMP,從行業的狀況來看,採用了微服務,但是有一點,首先對於應用本身暴露出來的服務,是和應用一起部署的,也就是並非單獨的部署,那麼業務元件介面暴露部署是否合理呢?答:業務元件的介面一般可以通過統一閘道器來管理。也可以對業務介面像spring cloud中設定訪問scope限制。

問題:所有暴露的微服務是否需要一個統一的服務管控和治理平臺?答:是的,一般有服務閘道器和服務發現元件來管理使用者請求。

問題:微服務的gateway需要實現底層多個細粒度的API組合的場景,我們現在一部分使用非同步,但是遇到了沒辦法全面的解藕。我想問問,對於此,使用響應式?還是非同步回撥式?它們的區別點會有哪些呢?答:使用哪種API方案,其實要看業務。如果後端業務需要強資料一致性,建議使用響應式的。反之,可以使用非同步回撥或者訊息佇列。

問題:uaa和netflix zull整合 可行嗎?是否做過這方面的嘗試?
答:可以。Zuul元件提供閘道器服務,uaa是基於OAuth2協議,提供授權服務的。微服務架構下,他們是獨立的,是可以自由組合的。舉個例子,可以在zuul元件的配置檔案中,為授權服務(auth-service)元件的指定路由表。

可以參考:https://gist.github.com/nevermosby/875b9f7b1799a6207832010d6eafcfc3

相關文章