Dubbo IP白名单(多协议 + Telnet)

背景

  • 当不想改动服务消费者的时候(如服务消费者太多,改动大),只修改服务生产者,如何做服务权限控制?
  • Dubbo 使用注册中心的情况下,可通过 Dubbo Admin 中的功能配置IP白名单规则,但在 Dubbo 无使用注册中心的情况下,如何设置IP白名单?

实现

IP白名单配置类

@Getter
@Configuration
public class IpWhiteList {
 
    /**
     * 是否开启白名单
     */
    @Value("${dubbo.ipwhite.enabled:true}")
    private boolean enabled;
 
    /**
     * IP白名单列表
     */
    @Value("${dubbo.ipwhite.list}")
    private List allowedIps;
}

多协议请求拦截

@Activate(group = CommonConstants.PROVIDER)
public class AccessFilter implements Filter {
 
    private IpWhiteList ipWhiteList;
 
    public AccessFilter(IpWhiteList ipWhiteList) {
        this.ipWhiteList = ipWhiteList;
    }
 
    @Override
    public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
        if (ipWhiteList.isEnabled()) {
            String remoteHost = RpcContext.getContext().getRemoteHost();
            String localHost = RpcContext.getContext().getLocalHost();
            if ((CollectionUtils.isEmpty(ipWhiteList.getAllowedIps()) && !remoteHost.equals(localHost))) {
                throw new RpcException("No Access");
            }
            if (!ipWhiteList.getAllowedIps().contains(remoteHost)) {
                throw new RpcException("No Access");
            }
        }
        return invoker.invoke(invocation);
    }
}

AccessFilter(IpWhiteList ipWhiteLis) 通过 Dubbo SPI 注入 IpWhiteList 对象。

新增配置 META-INFO/dubbo/org.apache.dubbo.rpc.Filter(若是Dubbo 2.7.0 版本以下,修改文件名为 com.alibaba.dubbo.rpc.Filter)内容,配置对应的 AccessFilter 类全限定名。

accessFilter=包名.AccessFilter

Telnet 请求拦截

@Activate(group = CommonConstants.PROVIDER)
public class TelnetHandlerWrapper implements TelnetHandler {
 
    private TelnetHandler telnetHandler;
 
    private IpWhiteList ipWhiteList;
 
    public TelnetHandlerWrapper(TelnetHandler telnetHandler, IpWhiteList ipWhiteList) {
        this.telnetHandler = telnetHandler;
        this.ipWhiteList = ipWhiteList;
    }
 
    public TelnetHandlerWrapper() {
    }
 
    @Override
    public String telnet(Channel channel, String message) throws RemotingException {
        if (ipWhiteList.isEnabled()) {
            String remoteHost = channel.getRemoteAddress().getHostString();
            String localHost = channel.getLocalAddress().getHostString();
            if (CollectionUtils.isEmpty(ipWhiteList.getAllowedIps()) && !remoteHost.equals(localHost)) {
                return "No Access";
            }
            if (!ipWhiteList.getAllowedIps().contains(remoteHost)) {
                return "No Access";
            }
        }
        return telnetHandler.telnet(channel, message);
    }
}

TelnetHandlerWrapper(TelnetHandler telnetHandler, IpWhiteList ipWhiteList) 通过 Dubbo SPI 注入具体操作的 TelnetHandlerIpWhiteList 对象。

新增文件 META-INFO/dubbo/internal/org.apache.dubbo.remoting.telnet.TelnetHandler(若是 dubbo2.7.0 版本以下,修改文件名为 com.alibaba.dubbo.remoting.telnet.TelnetHandler)内容,配置对应的 TelnetHandlerWrapper 类全限定名。

clear=包名.TelnetHandlerWrapper
exit=包名.TelnetHandlerWrapper
help=包名.TelnetHandlerWrapper
status=包名.TelnetHandlerWrapper
log=包名.TelnetHandlerWrapper
ls=包名.TelnetHandlerWrapper
ps=包名.TelnetHandlerWrapper
cd=包名.TelnetHandlerWrapper
pwd=包名.TelnetHandlerWrapper
invoke=包名.TelnetHandlerWrapper
trace=包名.TelnetHandlerWrapper
count=包名.TelnetHandlerWrapper
select=包名.TelnetHandlerWrapper
shutdown=包名.TelnetHandlerWrapper
对代码不明白地方可联系讨论或对写的不好的地方望不吝指教。

你可能感兴趣的:(Dubbo IP白名单(多协议 + Telnet))