微服务访问安全设计方案全探索
文章來源:https://segmentfault.com/a/1190000006785852
今天給大家帶來的是 數人云工程師文權在高效運維線上群的分享實錄。從傳統單體應用架構到微服務架構,安全問題一直是人們關注的重點,文權與大家分享了關于微服務訪問安全設計方案的探索與實踐。
我們首先從傳統單體應用架構下的訪問安全設計說起,然后分析現代微服務架構下,訪問安全涉及的原則,接著討論目前常用的幾種微服務架構下的訪問安全設計方案。最后,詳析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
總結
以上是生活随笔為你收集整理的微服务访问安全设计方案全探索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Altium Designer学习---
- 下一篇: JavaScript总结01