今天給大家?guī)?lái)的是 數(shù)人云 工程師文權(quán)在高效運(yùn)維線上群的分享實(shí)錄。從傳統(tǒng)單體應(yīng)用架構(gòu)到微服務(wù)架構(gòu),安全問(wèn)題一直是人們關(guān)注的重點(diǎn),文權(quán)與大家分享了關(guān)于微服務(wù)訪問(wèn)安全設(shè)計(jì)方案的探索與實(shí)踐。
我們首先從傳統(tǒng)單體應(yīng)用架構(gòu)下的訪問(wèn)安全設(shè)計(jì)說(shuō)起,然后分析現(xiàn)代微服務(wù)架構(gòu)下,訪問(wèn)安全涉及的原則,接著討論目前常用的幾種微服務(wù)架構(gòu)下的訪問(wèn)安全設(shè)計(jì)方案。最后,詳析Spring Cloud微服務(wù)架構(gòu)下如何解決訪問(wèn)安全的問(wèn)題。
一、傳統(tǒng)單體應(yīng)用的訪問(wèn)安全設(shè)計(jì)
上面的示意圖展示了單體應(yīng)用的訪問(wèn)邏輯。用戶通過(guò)客戶端發(fā)出http或者h(yuǎn)ttps請(qǐng)求,經(jīng)過(guò)負(fù)載均衡后,單體應(yīng)用收到請(qǐng)求。接著經(jīng)過(guò)auth層,進(jìn)行身份驗(yàn)證和權(quán)限批準(zhǔn),這里,一般會(huì)有跟后端數(shù)據(jù)庫(kù)的交互。通過(guò)后,將請(qǐng)求分發(fā)到對(duì)應(yīng)的功能邏輯層中去。完成相關(guān)操作后,返回結(jié)果給客戶端。
傳統(tǒng)單體應(yīng)用的訪問(wèn)安全設(shè)計(jì)——原則
從以上分析可以看到,傳統(tǒng)單體應(yīng)用的訪問(wèn)安全設(shè)計(jì)原則為:
第一,每次的用戶請(qǐng)求都需要驗(yàn)證是否安全,這里可以分兩種情況:
一種是沒(méi)有session的請(qǐng)求,需要經(jīng)過(guò)幾個(gè)步驟完成session化。一般為驗(yàn)證當(dāng)前用戶的credential,獲取當(dāng)前用戶的identity,這兩步都需要訪問(wèn)數(shù)據(jù)庫(kù)等持久化對(duì)象來(lái)完成,最后一步是為當(dāng)前可用創(chuàng)建session,返回給客戶端后,啟用該session。
另一種是有session的請(qǐng)求,只需驗(yàn)證請(qǐng)求中當(dāng)前session的有效性,即可繼續(xù)請(qǐng)求。
第二,用戶的操作請(qǐng)求都在后端單個(gè)進(jìn)程中執(zhí)行完成,完全依賴后端調(diào)用方法的可靠性。一旦出錯(cuò),應(yīng)用是無(wú)法再次重復(fù)請(qǐng)求。
傳統(tǒng)單體應(yīng)用的訪問(wèn)安全設(shè)計(jì)——優(yōu)勢(shì)和注意點(diǎn)
小結(jié),傳統(tǒng)單體應(yīng)用由于設(shè)計(jì)相對(duì)簡(jiǎn)單單一,暴露給外界的入口相對(duì)較少,從而具有被攻擊并造成危害性的可能小的優(yōu)勢(shì)。
也正是由于單體應(yīng)用簡(jiǎn)單單一的特點(diǎn),需要注意相關(guān)問(wèn)題:
應(yīng)用后端保存了所有的credential等敏感信息
一旦入侵了對(duì)這個(gè)應(yīng)用的請(qǐng)求,就有可能拿到所有的保存在后端的信息
應(yīng)用的每次操作一般都需要和數(shù)據(jù)庫(kù)進(jìn)行交互,造成數(shù)據(jù)庫(kù)負(fù)載變高
二、微服務(wù)架構(gòu)下,訪問(wèn)安全設(shè)計(jì)原則
先來(lái)看下這張典型的微服務(wù)設(shè)計(jì)架構(gòu)圖,如圖所示,有以下幾點(diǎn)特征:
每個(gè)服務(wù)只有權(quán)限去操作自己負(fù)責(zé)的那部分功能。
用戶請(qǐng)求的身份驗(yàn)證和權(quán)限批準(zhǔn)都由獨(dú)立的gateway服務(wù)來(lái)保障
對(duì)外服務(wù)的LB層無(wú)法直接與提供業(yè)務(wù)服務(wù)的應(yīng)用層進(jìn)行訪問(wèn)
從上面的特征分析來(lái)看,想要給出一份訪問(wèn)安全設(shè)計(jì)的原則說(shuō)明,就要看看微服務(wù)架構(gòu)下,訪問(wèn)安全有哪些痛點(diǎn),以下羅列了幾點(diǎn):
單點(diǎn)登錄,即在微服務(wù)這種多獨(dú)立服務(wù)的架構(gòu)下,實(shí)現(xiàn)用戶只需要登錄一次就能訪問(wèn)所有相互信任的應(yīng)用系統(tǒng)
微服務(wù)架構(gòu)下的應(yīng)用一般都是無(wú)狀態(tài)的,導(dǎo)致用戶的請(qǐng)求每次都需要鑒權(quán),可能引發(fā)Auth服務(wù)的性能瓶頸
微服務(wù)架構(gòu)下,每個(gè)組件都管理著各自的功能權(quán)限,這種細(xì)粒度的鑒權(quán)機(jī)制需要事先良好的規(guī)劃
微服務(wù)架構(gòu)下,需要考慮到那些非瀏覽器端的客戶請(qǐng)求,是否具有良好的可操作性
根據(jù)實(shí)際情況,還有一些其他痛點(diǎn),這里不再一一贅述,而這些痛點(diǎn),就形成了我們?cè)跒槲⒎?wù)架構(gòu)設(shè)計(jì)訪問(wèn)安全的原則。
三、微服務(wù)架構(gòu)下,常用的訪問(wèn)安全設(shè)計(jì)方案
HTTP Basic Authentication Independent Auth DB
HTTP Basic Authentication Central Auth DB
API Tokens
SAML
這里列出4種,首先簡(jiǎn)單介紹下,然后一一敘述。
第一種,使用HTTP Basic Auth協(xié)議,加上獨(dú)立的Auth數(shù)據(jù)庫(kù)。
第二種,也是使用HTTP Basic Auth協(xié)議,跟第一種不同的是,使用集中式的Auth數(shù)據(jù)庫(kù)
第三種,API Tokens協(xié)議,這種大家應(yīng)該比較熟悉,很多公有服務(wù)(比如Github、Twitter等)的API都是用這種方式。
第四種,SAML,即Security Assertion Markup Language,翻譯過(guò)來(lái),是『安全聲明標(biāo)記語(yǔ)言』,它是基于XML的一種協(xié)議,企業(yè)內(nèi)使用得較多。
下面一一做介紹。
微服務(wù)常用訪問(wèn)安全設(shè)計(jì)方案——Basic Auth Independent Auth DB
第一種,如上示意圖所示,使用Basic Auth協(xié)議,配合每個(gè)服務(wù)自己都擁有存儲(chǔ)Credential敏感數(shù)據(jù)的數(shù)據(jù)庫(kù)(或者其他持久化倉(cāng)庫(kù))。
簡(jiǎn)單介紹下Basic Auth協(xié)議,它是在用戶的請(qǐng)求中添加一個(gè)Authorization消息頭,這個(gè)消息頭的值是一個(gè)固定格式:
Basic base64encode(username “:” password)
完整的消息頭列子為:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Basic Auth協(xié)議基本上被所有流行的網(wǎng)頁(yè)瀏覽器都支持。
這種方案的特點(diǎn):
每個(gè)提供功能的服務(wù)都擁有自己獨(dú)立的鑒權(quán)和授權(quán)機(jī)制
每個(gè)提供功能的服務(wù)都擁有自己獨(dú)立的數(shù)據(jù)庫(kù),來(lái)保存敏感信息
每次用戶請(qǐng)求都需要攜帶用戶的credential來(lái)完成操作
小結(jié)下使用這種方案的好處:
微服務(wù)的應(yīng)用可以實(shí)現(xiàn)100%無(wú)狀態(tài)化
基于Basic Auth開(kāi)發(fā)簡(jiǎn)單
同時(shí),小結(jié)下使用這種方案需要注意的地方:
由于每個(gè)服務(wù)都有自己存儲(chǔ)credential的機(jī)制,需要事先為每個(gè)服務(wù)設(shè)計(jì)好如何存儲(chǔ)和查找用戶的Credential
由于每次用戶請(qǐng)求都會(huì)攜帶用戶的Credential,需要事先設(shè)計(jì)好如何管理鑒權(quán)機(jī)制
微服務(wù)常用訪問(wèn)安全設(shè)計(jì)方案——Basic Auth Central Auth DB
第二種,如上示意圖所示,使用Basic Auth協(xié)議,與第一種方案相比,每個(gè)服務(wù)共用有同一個(gè)Auth DB。
第二種方案的特點(diǎn)和第一種很相似:
每個(gè)提供功能的服務(wù)都擁有自己獨(dú)立的鑒權(quán)和授權(quán)機(jī)制
每個(gè)提供功能的服務(wù)共用同一個(gè)DB,來(lái)保存Credential等敏感信息
每次用戶請(qǐng)求都需要攜帶用戶的credential來(lái)完成操作
小結(jié)下使用第二種方案的好處:
除了擁有第一種方案相似的好處外,由于共用了同一個(gè)持久化倉(cāng)庫(kù)來(lái)管理用戶信息,簡(jiǎn)化了原來(lái)獨(dú)立管理的機(jī)制
同時(shí),小結(jié)下使用這種方案需要注意的地方:
中心化Auth DB會(huì)被每次用戶請(qǐng)求來(lái)訪問(wèn)連接,可能引發(fā)AuthDB性能瓶頸
需要在每個(gè)服務(wù)中實(shí)現(xiàn)對(duì)共有Auth DB查找用戶信息的邏輯
微服務(wù)常用訪問(wèn)安全設(shè)計(jì)方案——API Tokens
第三種,如上示意圖所示,使用Token Based協(xié)議來(lái)對(duì)用戶請(qǐng)求進(jìn)行操作鑒權(quán)。
簡(jiǎn)單介紹下最基本的Token Based的交互方式:
用戶使用包含用戶名和密碼的credential從客戶端發(fā)起資源請(qǐng)求
后端接受請(qǐng)求,通過(guò)授權(quán)中心,生產(chǎn)有效token字符串,返回給客戶端
客戶端獲得token后,再次發(fā)出資源請(qǐng)求
后端接受帶token的請(qǐng)求,通過(guò)授權(quán)中心,獲取相關(guān)資源,返回給客戶端
業(yè)界常用的OAuth就是基于Token Based這套邏輯,實(shí)現(xiàn)的互聯(lián)網(wǎng)級(jí)的鑒權(quán)機(jī)制。
第三種方案的特點(diǎn)明顯:
使用token來(lái)進(jìn)行鑒權(quán),替換用戶本身的用戶名和密碼,提高了交互安全性
每次用戶請(qǐng)求需要攜帶有效token,與Auth服務(wù)進(jìn)行交互驗(yàn)證
小結(jié)下使用第三種方案的好處:
由于使用了token來(lái)鑒權(quán),業(yè)務(wù)服務(wù)不會(huì)看到用戶的敏感信息
同時(shí),小結(jié)下使用這種方案需要注意的地方:
Auth服務(wù)可能需要處理大量的生產(chǎn)token的操作
微服務(wù)常用訪問(wèn)安全設(shè)計(jì)方案——SAML
第四種,如上示意圖所示,使用SAML協(xié)議來(lái)對(duì)用戶請(qǐng)求進(jìn)行操作鑒權(quán)。它是一個(gè)基于XML的標(biāo)準(zhǔn),用于在不同的安全域(security domain)之間交換認(rèn)證和授權(quán)數(shù)據(jù)。在SAML標(biāo)準(zhǔn)定義了身份提供者(identity provider)和服務(wù)提供者(service provider),這兩者構(gòu)成了前面所說(shuō)的不同的安全域。
以上圖Google提供的Apps SSO的機(jī)制,簡(jiǎn)單介紹下SAML鑒權(quán)的交互方式:
用戶請(qǐng)求訪問(wèn)自建的google application
當(dāng)前application 生成一個(gè) SAML 身份驗(yàn)證請(qǐng)求。SAML 請(qǐng)求將進(jìn)行編碼并嵌入到SSO 服務(wù)的網(wǎng)址中。
當(dāng)前application將重定向發(fā)送到用戶的瀏覽器。重定向網(wǎng)址包含應(yīng)向SSO 服務(wù)提交的編碼 SAML 身份驗(yàn)證請(qǐng)求。
SSO(統(tǒng)一認(rèn)證中心或叫Identity Provider)解碼 SAML 請(qǐng)求,并提取當(dāng)前application的 ACS(聲明客戶服務(wù))網(wǎng)址以及用戶的目標(biāo)網(wǎng)址(RelayState 參數(shù))。然后,統(tǒng)一認(rèn)證中心對(duì)用戶進(jìn)行身份驗(yàn)證。
統(tǒng)一認(rèn)證中心生成一個(gè) SAML 響應(yīng),其中包含經(jīng)過(guò)驗(yàn)證的用戶的用戶名。按照 SAML 2.0 規(guī)范,此響應(yīng)將使用統(tǒng)一認(rèn)證中心的 DSA/RSA 公鑰和私鑰進(jìn)行數(shù)字簽名。
統(tǒng)一認(rèn)證中心對(duì) SAML 響應(yīng)和 RelayState 參數(shù)進(jìn)行編碼,并將該信息返回到用戶的瀏覽器。統(tǒng)一認(rèn)證中心提供了一種機(jī)制,以便瀏覽器可以將該信息轉(zhuǎn)發(fā)到當(dāng)前application ACS。
當(dāng)前application使用統(tǒng)一認(rèn)證中心的公鑰驗(yàn)證 SAML 響應(yīng)。如果成功驗(yàn)證該響應(yīng),ACS 則會(huì)將用戶重定向到目標(biāo)網(wǎng)址。
用戶將重定向到目標(biāo)網(wǎng)址并登錄到當(dāng)前application。
目前SAML在業(yè)界也有相當(dāng)?shù)氖褂枚?,包括IBM Weblogic等產(chǎn)品。
第四種方案的特點(diǎn)有:
由Identity Provider提供可信的簽名聲明
服務(wù)的訪問(wèn)安全由可信的Identity Provider提供
小結(jié)下使用第四種方案的好處:標(biāo)準(zhǔn)的可信訪問(wèn)模型
同時(shí),小結(jié)下使用這種方案需要注意的地方:
基于XML協(xié)議,傳輸相對(duì)復(fù)雜
對(duì)非瀏覽器客戶端適配不方便
四、Spring Cloud Security解決方案
Spring Cloud Security特點(diǎn)有:
基于OAuth2 和OpenID協(xié)議的可配置的SSO登錄機(jī)制
基于tokens保障資源訪問(wèn)安全
引入U(xiǎn)AA鑒權(quán)服務(wù),UAA是一個(gè)Web服務(wù),用于管理賬戶、Oauth2客戶端和用戶用于鑒權(quán)的問(wèn)題令牌(Issue Token)。UAA實(shí)現(xiàn)了Oauth2授權(quán)框架和基于JWT(JSON web tokens)的問(wèn)題令牌。
下面簡(jiǎn)單介紹下UAA,事實(shí)上,它是由CloudFoundry發(fā)起的,也是CloudFoundry平臺(tái)的身份管理服務(wù)( https://docs.cloudfoundry.org/ ... .html )。
主要功能是基于OAuth2,當(dāng)用戶訪問(wèn)客戶端應(yīng)用時(shí),生成并發(fā)放token給目標(biāo)客戶端。
UAA認(rèn)證服務(wù)包含如下幾個(gè)方面的內(nèi)容:
認(rèn)證對(duì)象。如用戶、客戶端以及目標(biāo)資源服務(wù)器
認(rèn)證類型。主要有授權(quán)碼模式、密碼模式以及客戶端模式
認(rèn)證范圍,即認(rèn)證權(quán)限,并作為一個(gè)命名的參數(shù)附加到AccessToken上。
接下來(lái),結(jié)合實(shí)例,一起來(lái)看下UAA在Spring Cloud中的實(shí)踐。
如圖所示,這是一個(gè)簡(jiǎn)單的基于Spring Cloud微服務(wù)架構(gòu)的例子,它的主要組件有:
Eureka組件提供服務(wù)發(fā)現(xiàn)功能
獨(dú)立的Config組件提供類似配置中心的服務(wù),持久化層可以是文件系統(tǒng),也可是git repository
Auth組件提供基于UAA的鑒權(quán)服務(wù)
Account組件保存用戶的業(yè)務(wù)信息
其他組件不一一介紹了
這里主要講Auth組件和Account組件是如何基于UAA服務(wù)進(jìn)行認(rèn)證和授權(quán)。
圖一為Auth組件業(yè)務(wù)代碼中定義了不同客戶端的認(rèn)證類型和認(rèn)證范圍,其中:
瀏覽器端的認(rèn)證類型是password,認(rèn)證范圍是ui
account組件端的認(rèn)證類型是client_credentials,認(rèn)證范圍是server
圖二為config組件(配置中心)定義的請(qǐng)求路由的規(guī)則,其中:
來(lái)轉(zhuǎn)發(fā)基于uaa的認(rèn)證請(qǐng)求至auth組件
來(lái)轉(zhuǎn)發(fā)請(qǐng)求至account組件,并標(biāo)記serviceId為account-service,與圖一中的withClient對(duì)應(yīng)。
圖一為瀏覽器打開(kāi)應(yīng)用入口后,輸入用戶名和密碼后,發(fā)出的認(rèn)證請(qǐng)求:
認(rèn)證url為/uaa/oauth/token,這是uaa模式下標(biāo)準(zhǔn)的請(qǐng)求獲取token的url
表單中包含了字段scope(認(rèn)證范圍)和字段password(認(rèn)證類型)
圖二為圖一發(fā)出認(rèn)證請(qǐng)求的返回結(jié)果:
Access_token為有效認(rèn)證token,將來(lái)被其他請(qǐng)求使用
圖三為發(fā)出獲取當(dāng)前用戶的信息的請(qǐng)求:
在請(qǐng)求里的Authorization的值為圖二中獲得的access_token
圖一為Account組件在Config組件(配置中心)定義的OAuth2協(xié)議下獲取token的方式,這里定義了:
clientID和clientSecret
accessTokenUrl,這里指定了auth組件的uaa獲取token的url
grant-type,即認(rèn)證類型,這里指定為client_credentials
scope,這里指定了server,說(shuō)明是這個(gè)認(rèn)證請(qǐng)求只適用在各微服務(wù)之間的訪問(wèn)。
圖二為Accout組件業(yè)務(wù)代碼中定義了需要使用Auth組件進(jìn)行事先鑒權(quán)的方法:
使用@PreAuthorize
annotation中可以指定認(rèn)證范圍的具體條件,這里是限定了server或者是demo賬戶,才有權(quán)限發(fā)起認(rèn)證。
最后小結(jié)下Spring Cloud Security的特點(diǎn):
基于UAA,使用OAuth2協(xié)議。不會(huì)暴露用戶的敏感信息
基于認(rèn)證類型和認(rèn)證范圍,實(shí)現(xiàn)細(xì)粒度的鑒權(quán)機(jī)制
非瀏覽器客戶端下良好的操作性
Q&A
問(wèn)題:Basic Auth Central Auth DB這種方式中,每個(gè)服務(wù)有自己的鑒權(quán)DB,這塊只是一個(gè)緩沖嗎?如果中途通過(guò)別的方式修改了中心DB的數(shù)據(jù),而緩沖又沒(méi)過(guò)期,這個(gè)時(shí)候有什么解決方案嗎?
答:不是緩沖,這里的Central Auth DB是指各個(gè)微服務(wù)共用一個(gè)數(shù)據(jù)庫(kù)。
問(wèn)題:微服務(wù)架構(gòu)需要服務(wù)路由和服務(wù)注冊(cè)么?跟esb的區(qū)別在哪里?
答:服務(wù)路由組件和服務(wù)注冊(cè)組件和是相對(duì)必要的,他們保證了用戶請(qǐng)求能發(fā)到正確的微服務(wù)中去。ESB企業(yè)服務(wù)總線是相對(duì)比較重的組件,而不是像微服務(wù)組件一樣只負(fù)責(zé)單個(gè)業(yè)務(wù)。
問(wèn)題:在微服務(wù)中,對(duì)于數(shù)據(jù)權(quán)限的粒度,是可以集中在在gateway中進(jìn)行還是由每個(gè)微服務(wù)自己獨(dú)立配置?
答:推薦由那個(gè)專門負(fù)載權(quán)限的微服務(wù)組件來(lái)配置。
問(wèn)題:您好,辛苦了,請(qǐng)問(wèn)現(xiàn)在有類似SAML協(xié)議,但是不基于XML,而是基于JSON或者其他簡(jiǎn)化格式的協(xié)議嗎?
答:目前據(jù)我所知沒(méi)有基于JSON的SAML協(xié)議。有個(gè)叫JWT(JSON web token)的協(xié)議,它是完全基于JSON的,Spring Cloud架構(gòu)中也使用了JWT。
問(wèn)題:對(duì)于這個(gè)架構(gòu),服務(wù)劃分的粒度有沒(méi)有什么好的建議?另外登錄憑證保存在客戶端如何解決報(bào)文被攔截的安全漏洞?
答:服務(wù)劃分需要按具體業(yè)務(wù)來(lái)說(shuō),一般來(lái)說(shuō),一個(gè)業(yè)務(wù)實(shí)體作為一個(gè)微服務(wù)。使用https可以一定程度上提高安全性。
問(wèn)題:spring cloud security可以解決token重放攻擊么?
答:token重放攻擊不是特別了解,可能是數(shù)據(jù)弱一致性導(dǎo)致的,建議設(shè)計(jì)盡可能短的過(guò)期時(shí)間。
問(wèn)題:我們公司現(xiàn)在在設(shè)計(jì)DMP,從行業(yè)的狀況來(lái)看,采用了微服務(wù),但是有一點(diǎn),首先對(duì)于應(yīng)用本身暴露出來(lái)的服務(wù),是和應(yīng)用一起部署的,也就是并非單獨(dú)的部署,那么業(yè)務(wù)組件接口暴露部署是否合理呢?
答:業(yè)務(wù)組件的接口一般可以通過(guò)統(tǒng)一網(wǎng)關(guān)來(lái)管理。也可以對(duì)業(yè)務(wù)接口像spring cloud中設(shè)置訪問(wèn)scope限制。
問(wèn)題:所有暴露的微服務(wù)是否需要一個(gè)統(tǒng)一的服務(wù)管控和治理平臺(tái)?
答:是的,一般有服務(wù)網(wǎng)關(guān)和服務(wù)發(fā)現(xiàn)組件來(lái)管理用戶請(qǐng)求。
問(wèn)題:微服務(wù)的gateway需要實(shí)現(xiàn)底層多個(gè)細(xì)粒度的API組合的場(chǎng)景,我們現(xiàn)在一部分使用異步,但是遇到了沒(méi)辦法全面的解藕。我想問(wèn)問(wèn),對(duì)于此,使用響應(yīng)式?還是異步回調(diào)式?它們的區(qū)別點(diǎn)會(huì)有哪些呢?
答:使用哪種API方案,其實(shí)要看業(yè)務(wù)。如果后端業(yè)務(wù)需要強(qiáng)數(shù)據(jù)一致性,建議使用響應(yīng)式的。反之,可以使用異步回調(diào)或者消息隊(duì)列。
問(wèn)題:uaa和netflix zull集成 可行嗎?是否做過(guò)這方面的嘗試?
答:可以。Zuul組件提供網(wǎng)關(guān)服務(wù),uaa是基于OAuth2協(xié)議,提供授權(quán)服務(wù)的。微服務(wù)架構(gòu)下,他們是獨(dú)立的,是可以自由組合的。舉個(gè)例子,可以在zuul組件的配置文件中,為授權(quán)服務(wù)(auth-service)組件的指定路由表。可參照: https://gist.github.com/neverm ... fcfc3
聯(lián)系客服