微服務(wù)鑒權(quán)設(shè)計(jì)的幾種方案
- Token透傳(不推薦)
- Fegin內(nèi)部調(diào)用方式
- Dubbo內(nèi)部調(diào)用方式
- Spring Boot Web + Dubbo內(nèi)部調(diào)用方式
- 常規(guī)模式
- 與K8S集成
Token透傳(不推薦)
剛開始接觸微服務(wù)時(shí)網(wǎng)上給的方案大都數(shù)是通過透傳Token做鑒權(quán),但我認(rèn)為這種方式不是很妥當(dāng)。接著往下看:
圖片
這種方式通過透傳Token使得各微服務(wù)都能獲取到當(dāng)前登錄人信息,在代碼編寫上確實(shí)可能會(huì)方便,但我認(rèn)為這不是一種很好的設(shè)計(jì)方式。
原因一:內(nèi)部API與外部API混合在一起不太好區(qū)分。
原因二:內(nèi)部調(diào)用的微服務(wù)API因該具備無狀態(tài)性質(zhì),這樣才能保證方法的原子性以提高代碼復(fù)用率。
換句話說:B服務(wù)提供API時(shí)不因該關(guān)心當(dāng)前是否為登錄狀態(tài),登錄狀態(tài)應(yīng)該由路由中的第一個(gè)服務(wù)校驗(yàn)維護(hù),在調(diào)用后續(xù)服務(wù)時(shí)應(yīng)該顯示的傳入相關(guān)參數(shù)。比如以下場景:
場景一:用戶簽到添加積分
場景二:后臺(tái)管理員給用戶手動(dòng)添加積分
場景三:分布式調(diào)度批量增加用戶積分
根據(jù)需求積分服務(wù)提供了一個(gè)給用戶添加積分的API,如果你的API是通過獲取的當(dāng)前登錄用戶ID增加的積分,那么面對(duì)場景二時(shí)你需要重新編寫一個(gè)給用戶添加積分的API,因?yàn)楫?dāng)前登錄的是后臺(tái)管理員而不是用戶(代碼復(fù)用率較低)
不透傳數(shù)據(jù),顯示的提供入?yún)?/h4>
圖片
路由到達(dá)的第一個(gè)服務(wù)已經(jīng)對(duì)Token進(jìn)行了解析認(rèn)證并將userId顯示的傳遞給了后續(xù)服務(wù),后續(xù)服務(wù)不需要再對(duì)token進(jìn)行解析認(rèn)證。根據(jù)1.1的三個(gè)場景只需要提供一個(gè)入?yún)瑄serId的API,保證了函數(shù)的原子性提供代碼復(fù)用率。
注意: 提供的API不能暴露給外網(wǎng),我們需要在路徑上做區(qū)分,避免外網(wǎng)非法訪問內(nèi)部API。我們可以訂好內(nèi)部調(diào)用API路徑規(guī)則,如:/api/inside/\** 。在網(wǎng)關(guān)層拒絕內(nèi)部調(diào)用API請(qǐng)求的訪問。
統(tǒng)一授權(quán)
統(tǒng)一授權(quán)是指:將API鑒權(quán)集中在應(yīng)用網(wǎng)關(guān)上
Fegin內(nèi)部調(diào)用方式
Spring Cloud Gateway + Fegin內(nèi)部調(diào)用,集中在Gateway上做統(tǒng)一認(rèn)證鑒權(quán),鑒權(quán)后在請(qǐng)求頭中添加鑒權(quán)后的信息轉(zhuǎn)發(fā)給后續(xù)服務(wù),如:userId等。。。
圖片
缺點(diǎn):A服務(wù)調(diào)用B服務(wù)時(shí),B服務(wù)需要寫一個(gè)內(nèi)部調(diào)用的Controller接口A服務(wù)才能通過Fegin調(diào)用到B服務(wù),增加了代碼量(這里的設(shè)計(jì)方案是內(nèi)部調(diào)用與外部調(diào)用Controller是分開的)
Dubbo內(nèi)部調(diào)用方式
Spring Cloud Gateway + Dubbo內(nèi)部調(diào)用,集中在Gateway上做統(tǒng)一認(rèn)證鑒權(quán),鑒權(quán)后在請(qǐng)求頭中添加鑒權(quán)后的信息轉(zhuǎn)發(fā)給后續(xù)服務(wù),如:userId等。。。
優(yōu)點(diǎn):與第一種相比不需要額外編寫一個(gè)Controller接口,只有本地service與遠(yuǎn)程DubboService的區(qū)別,代碼更簡潔。
缺點(diǎn):項(xiàng)目技術(shù)棧略微增加了復(fù)雜度。

Spring Boot Web + Dubbo內(nèi)部調(diào)用方式
這里的設(shè)計(jì)方案直接去掉了Gateway,直接使用了一個(gè)Spring Boot Web項(xiàng)目來代替Gateway。但需要注意的是應(yīng)該將Web項(xiàng)目的容器換成Undertow,因?yàn)門omcat是阻塞式的容器,不換也不是不行,但吞吐量可能會(huì)少一下,Undertow是非阻塞式的容器,可以與Gateway到達(dá)相同的效果。(非阻塞式:當(dāng)請(qǐng)求為線程進(jìn)入阻塞狀態(tài)時(shí),當(dāng)前線程會(huì)被掛起,當(dāng)前的計(jì)算資源會(huì)去做別的事情,當(dāng)被掛起的線程收到響應(yīng)時(shí)才會(huì)被繼續(xù)執(zhí)行,壓榨CPU用更少的資源做更多的事情,但并不會(huì)提升性能)
因?yàn)槿サ袅薌ateway我們需要將所有服務(wù)的Controller集成到Web應(yīng)用,然后在這個(gè)Web應(yīng)用上做統(tǒng)一認(rèn)證授權(quán)。如果將所有代碼寫到Web應(yīng)用中,這樣可能不合適,我們可以選擇每個(gè)服務(wù)創(chuàng)建一個(gè)Controller模塊,Web網(wǎng)關(guān)服務(wù)只有一個(gè)啟動(dòng)類,通過依賴的方式集成所有服務(wù)的Controller。
優(yōu)點(diǎn):簡化了項(xiàng)目結(jié)構(gòu),所有服務(wù)只有service代碼。性能壓測時(shí)不用考慮Gateway的線程池使用情況,業(yè)務(wù)服務(wù)只需要考慮Dubbo線程池的使用情況。
缺點(diǎn):沒辦法通過配置中心動(dòng)態(tài)調(diào)整路由。比如說增加了一個(gè)服務(wù)Gateway可以不重啟通過配置中心增加路由配置即可。

非統(tǒng)一授權(quán)
非統(tǒng)一授權(quán):不在應(yīng)用網(wǎng)關(guān)上集成鑒權(quán),網(wǎng)關(guān)只有單一的路由轉(zhuǎn)發(fā)業(yè)務(wù)。各位服務(wù)都有自己的鑒權(quán)方式,當(dāng)然也可以通過jar包的方式統(tǒng)一各服務(wù)的鑒權(quán)方式。
常規(guī)模式
通過編寫通用的鑒權(quán)模塊,各服務(wù)集成該模塊。該模塊具備以下功能:
- JWT Token解析
- 權(quán)限校驗(yàn)攔截
- 緩存(本地緩存\Redis緩存)
這種模式更適合大型項(xiàng)目團(tuán)隊(duì),可能各微服務(wù)都由一個(gè)項(xiàng)目組負(fù)責(zé)。各服務(wù)維護(hù)自己的權(quán)限規(guī)則(這里指的是權(quán)限規(guī)則數(shù)據(jù),規(guī)則是統(tǒng)一的)
圖片
該模式下由于應(yīng)用網(wǎng)關(guān)比較輕量級(jí),不再涉及復(fù)雜的鑒權(quán)流程,使得項(xiàng)目部署可以更靈活,當(dāng)我們使用K8S部署項(xiàng)目時(shí),我們可以將應(yīng)用網(wǎng)關(guān)替換成K8S中的Ingress網(wǎng)關(guān)。
我們先看常規(guī)模式部署在K8S中完整的鏈路:
圖片
當(dāng)用戶訪問時(shí)會(huì)先到達(dá)K8S Ingress網(wǎng)關(guān)通過應(yīng)用網(wǎng)關(guān)Service的負(fù)載均衡調(diào)用應(yīng)用網(wǎng)關(guān),應(yīng)用網(wǎng)關(guān)需要通過注冊中心獲取服務(wù)注冊列表,通過服務(wù)注冊列表負(fù)載均衡到后續(xù)服務(wù)。
與K8S集成
我們再來看看將應(yīng)用網(wǎng)關(guān)替換成K8S中的Ingress網(wǎng)關(guān)的完整鏈路:
圖片
這里不僅只是去掉了應(yīng)用網(wǎng)關(guān),同時(shí)我們通過K8S Service 負(fù)載均衡的能力去掉了注冊中心。減少了我們部署微服務(wù)時(shí)還要額外搭建一套注冊中心。同時(shí)減少了一層沒必要的轉(zhuǎn)發(fā)。至于K8S中的Service,大家可以理解成一個(gè)本地的host假域名,比如我們在K8S給商品創(chuàng)建一個(gè)Service,名稱為:goods-svc。那么我們可以通過goods-svc直連。如:
- http://goods-svc:8080/api/goods/info/10001
- dubbo://goods-svc:20880
方案沒有對(duì)錯(cuò),選擇適合自己的就是最好的。
相關(guān)鏈接:juejin.cn/post/7329352197837029385






























