过滤器(八)之TokenFilter
本文基于 Dubbo 2.6.1 版本,望知悉。
1. 概述
本文分享 TokenFilter 过滤器,用于服务提供者中,提供 令牌验证 的功能。在 《Dubbo 用户指南 —— 令牌验证》 定义如下:
通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者。
另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者。
认证流程
- 官方文档写的很全,胖友请点击链接看完哈。
So ,可能和大多数胖友(包括我),一开始理解和期望的不太一样 。
2.【服务消费者】随机 Token
在 ServiceConfig 的 #doExportUrlsFor1Protocol(protocolConfig, registryURLs) 方法中,随机生成 Token :
```plain text plain // 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); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
# 3.【服务消费者】接收 Token
服务**消费者**,从注册中心,获取服务提供者的 **URL** ,从而获得该服务着的 Token 。所以,即使服务提供者随机生成 Token ,消费者一样可以拿到。
# 3.【服务消费者】发送 Token
RpcInvocation 在创建时,“**自动**”带上 Token ,如下图所示:

RpcInvocation
# 4.【服务提供者】认证 Token
com.alibaba.dubbo.rpc.filter.TokenFilter ,实现 Filter 接口,**令牌验证** Filter 实现类。代码如下:
```plain text
plain @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); } }
本文由作者按照 CC BY 4.0 进行授权
