dubbo接口访问控制
微服務(wù)背景下,一個web應(yīng)用都可能不再service依賴,而是通過RPC調(diào)用遠端服務(wù)器上的服務(wù)。這些服務(wù)里,就包括了一些不能輕易暴露的后臺功能接口。暴露出去的dubbo接口注冊到某一個zk上后,該dubbo接口對注冊到該zk上的消費者都是可見的。對公司內(nèi)部而言,通常不會有人蓄意去調(diào)用一些敏感的接口,但也存在人為誤用的可能呀。為此,考慮通過白名單機制來控制dubbo接口的訪問。
現(xiàn)在以許可ip127.0.0.1訪問接口fundRecordTemplateFacade為例演示。
擴展Filter
首先,我們需要實現(xiàn)com.alibaba.dubbo.rpc.Filter接口:
@Activate(group = { Constants.CONSUMER, Constants.PROVIDER }) public class FacadeAccessFilter implements Filter { private FacadeAccessConfig facadeAccessConfig; public FacadeAccessConfig getFacadeAccessConfig() { return facadeAccessConfig; } // 通過setter方式注入白名單配置文件 public void setFacadeAccessConfig(FacadeAccessConfig facadeAccessConfig) { this.facadeAccessConfig = facadeAccessConfig; } @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { Result result = null; // 獲取調(diào)用的接口名 String reqFacade = invoker.getInterface().getSimpleName(); try { // 嘗試在白名單配置文件里查找定義的接口,如果找不到則catch住異常、并許可訪問。 Method method; try { method = facadeAccessConfig.getClass().getDeclaredMethod(editMethodName(reqFacade)); } catch (NoSuchMethodException e) { // 無特殊限制,則許可訪問 result = invoker.invoke(invocation); return result; } // 走到這里,說明白名單配置文件配了對該facade的訪問限制 // 獲取remoteAddress:進行訪問的應(yīng)用,格式ip:port String remoteAddress = RpcContext.getContext().getRemoteAddressString(); // 只取ip String remoteIp = remoteAddress.split(":")[0]; // 獲取licensinedApplications:許可的應(yīng)用列表 String licensinedApplications = (String) method.invoke(facadeAccessConfig); if (StringUtils.isNotEmpty(licensinedApplications) && StringUtils.isNotEmpty(remoteIp) && licensinedApplications.contains(remoteIp)) { // 權(quán)限許可、進行訪問 Help.log_info(getClass(), " remoteAddress" + remoteAddress + "訪問接口" + reqFacade); result = invoker.invoke(invocation); return result; } else { // 權(quán)限不許可、退出訪問 Help.log_info(getClass(), " remoteAddress" + remoteAddress + "無權(quán)訪問接口" + reqFacade); result = new RpcResult("remoteAddress" + remoteAddress + "無權(quán)訪問接口" + reqFacade); return result; } } catch (SecurityException e) { Help.log_error(getClass(), "校驗remoteAddress是否有權(quán)限訪問" + reqFacade + "發(fā)生異常", e); } catch (IllegalAccessException e) { Help.log_error(getClass(), "校驗remoteAddress是否有權(quán)限訪問" + reqFacade + "發(fā)生異常", e); } catch (IllegalArgumentException e) { Help.log_error(getClass(), "校驗remoteAddress是否有權(quán)限訪問" + reqFacade + "發(fā)生異常", e); } catch (InvocationTargetException e) { Help.log_error(getClass(), "校驗remoteAddress是否有權(quán)限訪問" + reqFacade + "發(fā)生異常", e); } return result; } private String editMethodName(String fieldName) { return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length()); } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
配置文件
在resources目錄下添加純文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,內(nèi)容如下:?
修改配置文件dubbo-common.xml,在dubbo:provider屬性中添加配置的filter,內(nèi)容如下:?
擴展Filter時,我們是通過setter方法將訪問白名單FacadeAccessConfig注冊到FacadeAccessFilter類中的,那么在配置文件(譬如:applicationContext.xml)里還需要對bean實例化。
- 1
- 2
- 3
- 4
- 5
訪問白名單文件
我們看一下白名單文件的設(shè)計格式。本意希望能配置成”接口名=調(diào)用接口的應(yīng)用名”,因為部署應(yīng)用的ip變化可能性遠高于應(yīng)用本身的名稱修改。但是在Invoker和Invocation對象中找不到客戶端的應(yīng)用名,無奈之下,就設(shè)計成了”接口名=調(diào)用接口的ip”。?
下面是FacadeAccessConfig類,定義的私有屬性都是需要控制權(quán)限的dubbo接口名,getter方法從配置平臺disconf上找到對應(yīng)配置文件的對應(yīng)屬性值。
@Component(value = "facadeAccessConfig") @DisconfFile(filename = "facadeAccessConfig.properties") public class FacadeAccessConfig { // 定義可以訪問fundRecordTemplateFacade的應(yīng)用 private String fundRecordTemplateFacade; @DisconfFileItem(associateField = "fundRecordTemplateFacade", name = "fundRecordTemplateFacade") public String getFundRecordTemplateFacade() { return fundRecordTemplateFacade; } public void setFundRecordTemplateFacade(String fundRecordTemplateFacade) { this.fundRecordTemplateFacade = fundRecordTemplateFacade; } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
這樣,對于已經(jīng)配置的一個接口,新增可訪問的應(yīng)用只需要添加ip。對于一個新配置的接口,只需要在配置文件facadeAccessConfig.properties里添加”接口名=調(diào)用接口的應(yīng)用名”,然后在FacadeAccessConfig類中新增私有屬性即可。
轉(zhuǎn)載于:https://www.cnblogs.com/exmyth/p/8654959.html
總結(jié)
以上是生活随笔為你收集整理的dubbo接口访问控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博客作业02---线性表
- 下一篇: 2018年各大互联网前端面试题三(阿里)