SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)之網(wǎng)關(guān)授權(quán)VS微服務(wù)授權(quán)
本文轉(zhuǎn)載自微信公眾號(hào)「JAVA日知錄」,作者單一色調(diào)。轉(zhuǎn)載本文請(qǐng)聯(lián)系JAVA日知錄公眾號(hào)。
在SpringCloud架構(gòu)中,實(shí)現(xiàn)授權(quán)功能有兩種實(shí)現(xiàn)方式:
- 在網(wǎng)關(guān)層進(jìn)行授權(quán)
- 由后端微服務(wù)自己授權(quán)
兩種方式在此系列文章中都有實(shí)現(xiàn)方案,那么問題來了:哪種才是最優(yōu)方案,哪種方案更合理呢?
很抱歉,看完這篇文章你也不一定能得到你想要的答案,因?yàn)榻Y(jié)論是并沒有最優(yōu)方案,兩種方案各有千秋,只有根據(jù)自身業(yè)務(wù)選擇對(duì)應(yīng)的方案。本文我們將兩種方案做一個(gè)簡(jiǎn)單對(duì)比,以便大伙在做方案決策有個(gè)選擇參考。
解決方案對(duì)比
首先我們看看兩種方案實(shí)現(xiàn)的原理:如果對(duì)具體實(shí)現(xiàn)方式有疑問的同學(xué)可以參考這篇文章:
SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)十九 - 集成RBAC授權(quán)
網(wǎng)關(guān)授權(quán)
基于網(wǎng)關(guān)授權(quán)我們又叫基于路徑匹配器授權(quán),請(qǐng)求在經(jīng)過網(wǎng)關(guān)的時(shí)候校驗(yàn)當(dāng)前請(qǐng)求的路徑是否在用戶擁有的資源路徑中。
在基于路徑匹配器授權(quán)時(shí)需要考慮restful風(fēng)格的訪問路徑,如 /account-service/blog/user/{id} 或 /account-service/blog/**等,所以在網(wǎng)關(guān)進(jìn)行授權(quán)主要是基于通配符匹配。
微服務(wù)授權(quán)
微服務(wù)授權(quán)我們又叫基于方法攔截,在資源上打上對(duì)應(yīng)的方法標(biāo)識(shí)然后分配給用戶。在請(qǐng)求方法上通過對(duì)應(yīng)的注解判斷當(dāng)前用戶是否有訪問此方法的權(quán)限。如SpringSecurity中的 @PreAuthorize("hasAuthority('')")注解,Shiro中的 @RequiresPermissions('')注解。不管是SpringSecurity還是Shiro他們實(shí)現(xiàn)原理都是基于關(guān)鍵字完全匹配。
優(yōu)缺點(diǎn)對(duì)比
網(wǎng)關(guān)授權(quán)
優(yōu)點(diǎn)
使用網(wǎng)關(guān)授權(quán)的優(yōu)點(diǎn)很明顯,后端所有微服務(wù)只需要是普通的服務(wù)即可,不再需要依賴權(quán)限那一套。
缺點(diǎn)
通配符匹配在網(wǎng)關(guān)做性能比較差,通配符要拆分,先匹配前綴,前綴匹配了再匹配通配符。這里大家可以看看org.springframework.util.AntPathMatcher#doMatch()的實(shí)現(xiàn)邏輯。
對(duì)于Restful風(fēng)格的URL路徑,不能精細(xì)化控制權(quán)限
例如一個(gè)微服務(wù)有如下API
- GET /v1/pb/user
- POST /v1/pb/user
- PUT /v1/pb/user
這樣在網(wǎng)關(guān)通過request.getURI().getPath()方法獲取到用戶請(qǐng)求路徑的時(shí)候都是同一個(gè)地址,給一個(gè)用戶授予/v1/pb/user權(quán)限后他就擁有了GET、PUT、POST三種不同權(quán)限,很顯然這樣不能滿足精細(xì)權(quán)限控制。
至于如何解決這個(gè)問題,原來專門寫過一篇文章討論,感興趣的同學(xué)可以看看:SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)二十五 - Restful接口攔截
微服務(wù)授權(quán)
優(yōu)點(diǎn):
上面提到網(wǎng)關(guān)授權(quán)的缺點(diǎn)實(shí)際上是微服務(wù)授權(quán)的優(yōu)點(diǎn),基于方法攔截是完全匹配,cpu消耗很少,而且也不存在RestFul的問題。
缺點(diǎn):
實(shí)現(xiàn)較為復(fù)雜,在 SpringSecurity Oauth2體系中需要全部引入資源服務(wù)器相關(guān)配置,所以一般會(huì)建立一個(gè)單獨(dú)的資源服務(wù)器模塊,這也是系列文章下篇內(nèi)容需要解決的問題。
結(jié)論
這里我們嘗試對(duì)兩種實(shí)現(xiàn)方案做一個(gè)總結(jié),如果系統(tǒng)功能、業(yè)務(wù)模塊不是很多可以采用網(wǎng)關(guān)授權(quán)模式,這樣實(shí)現(xiàn)最簡(jiǎn)單也最方便,雖然存在Restful風(fēng)格不能精細(xì)化權(quán)限控制問題,但是我們加一個(gè)Method字段就可以解決。
如果你的系統(tǒng)規(guī)模比較大,有很多資源需要授權(quán)那就建議采用微服務(wù)授權(quán)模式,那為了避免每個(gè)微服務(wù)都需要處理權(quán)限校驗(yàn)的邏輯,我們還需要抽取一個(gè)公共的權(quán)限認(rèn)證模塊供后端服務(wù)引用。