我是一段不羁的公告!
记得给艿艿这 3 个项目加油,添加一个 STAR 噢。
https://github.com/YunaiV/SpringBoot-Labs
https://github.com/YunaiV/onemall
https://github.com/YunaiV/ruoyi-vue-pro

精尽 Dubbo 源码分析 —— 过滤器(八)之 TokenFilter

本文基于 Dubbo 2.6.1 版本,望知悉。

1. 概述

本文分享 TokenFilter 过滤器,用于服务提供者中,提供 令牌验证 的功能。在 《Dubbo 用户指南 —— 令牌验证》 定义如下:

通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者。

另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者。

认证流程

  • 官方文档写的很全,胖友请点击链接看完哈。

So ,可能和大多数胖友(包括我),一开始理解和期望的不太一样 🙂 。

2.【服务消费者】随机 Token

在 ServiceConfig 的 #doExportUrlsFor1Protocol(protocolConfig, registryURLs) 方法中,随机生成 Token :

// token ,参见《令牌校验》http://dubbo.apache.org/zh-cn/docs/user/demos/token-authorization.html
if (!ConfigUtils.isEmpty(token)) {
if (ConfigUtils.isDefault(token)) { // true || default 时,UUID 随机生成
map.put("token", UUID.randomUUID().toString());
} else {
map.put("token", token);
}
}

3.【服务消费者】接收 Token

服务消费者,从注册中心,获取服务提供者的 URL ,从而获得该服务着的 Token 。
所以,即使服务提供者随机生成 Token ,消费者一样可以拿到。

3.【服务消费者】发送 Token

RpcInvocation 在创建时,“自动”带上 Token ,如下图所示:

RpcInvocation

4.【服务提供者】认证 Token

com.alibaba.dubbo.rpc.filter.TokenFilter ,实现 Filter 接口,令牌验证 Filter 实现类。代码如下:

@Activate(group = Constants.PROVIDER, value = Constants.TOKEN_KEY)
public class TokenFilter implements Filter {

@Override
public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
// 获得服务提供者配置的 Token 值
String token = invoker.getUrl().getParameter(Constants.TOKEN_KEY);
if (ConfigUtils.isNotEmpty(token)) {
// 从隐式参数中,获得 Token 值。
Class<?> serviceType = invoker.getInterface();
Map<String, String> attachments = inv.getAttachments();
String remoteToken = attachments == null ? null : attachments.get(Constants.TOKEN_KEY);
// 对比,若不一致,抛出 RpcException 异常
if (!token.equals(remoteToken)) {
throw new RpcException("Invalid token! Forbid invoke remote service " + serviceType + " method " + inv.getMethodName() + "() from consumer " + RpcContext.getContext().getRemoteHost() + " to provider " + RpcContext.getContext().getLocalHost());
}
}
// 服务调用
return invoker.invoke(inv);
}

}

666. 彩蛋

再来一发水文。

知识星球

总访客数 && 总访问量