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