背景
- 当不想改动服务消费者的时候(如服务消费者太多,改动大),只修改服务生产者,如何做服务权限控制?
- 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<String> 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-INF/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 注入具体操作的 TelnetHandler
和 IpWhiteList
对象。
新增文件 META-INF/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