第3章:RMC认证模型:基于Capability的认证机制

好,咱们今天聊点硬核的。RMC认证模型的核心,说白了就是一句话:你手里有什么,你就能干什么。听起来像废话?别急,我慢慢给你拆。

传统的RBAC(基于角色的访问控制)大家都很熟悉了——你是个管理员,你就能删库;你是个普通用户,你只能看看。但问题来了:角色是静态的,权限是绑死的。一旦角色被赋予,你就能一直用,直到有人手动回收。这在微服务、分布式系统里,简直就是灾难。

RMC模型换了个思路:不认人,只认令牌。这个令牌,就是Capability(能力凭证)。你拿着它,就能做对应的事;丢了它,就啥也干不了。说白了,权限跟着令牌走,不跟着人走。

3.1 什么是Capability?

Capability,你可以把它想象成一把数字钥匙。这把钥匙上刻着两样东西:

  • 资源标识:你能访问哪个资源(比如某个订单、某台服务器)
  • 操作权限:你能对这个资源做什么(读、写、删除、执行)

举个例子:

{
  "capability_id": "cap_abc123",
  "resource": "order:98765",
  "actions": ["read", "update"],
  "expires_at": "2025-12-31T23:59:59Z",
  "issuer": "auth-service"
}

这个Capability表示:持有者可以读取和更新订单98765,有效期到年底。没有别的权限,一点不多,一点不少。

核心思想:Capability是最小权限原则的完美体现。你只拿到你需要的,不多给一分。

3.2 Capability的生成与分发

好,那Capability是怎么来的?总不能用户自己造吧?

生成流程其实不复杂,我画个图你就明白了:

用户 认证服务 策略引擎 ① 请求令牌 ② 查询策略 ③ 返回策略 ④ 生成Capability ⑤ 返回令牌 资源服务 ⑥ 携带令牌访问

流程其实就五步:

  1. 用户请求令牌:用户向认证服务发起请求,带上自己的身份凭证(比如JWT、API Key)
  2. 认证服务查询策略:认证服务拿着用户身份,去策略引擎查一下:这人能干啥?
  3. 策略引擎返回策略:策略引擎根据预设规则,返回该用户允许的操作列表
  4. 认证服务生成Capability:认证服务把策略打包成一个Capability令牌,签名防篡改
  5. 返回令牌给用户:用户拿到Capability,后面就靠它说话了

我的经验:我在项目中遇到过一个问题——Capability生成时没加过期时间,结果一个测试令牌在生产环境跑了三个月。后来我强制要求:所有Capability必须带expires_at字段,且默认不超过24小时。血的教训啊。

3.3 Capability的验证流程

用户拿到Capability后,怎么用?很简单:每次请求资源时,把Capability带上。资源服务收到请求后,做三件事:

步骤 操作 说明
1 验签 检查Capability的签名是否有效,防止伪造
2 校验有效期 检查是否过期,过期的直接拒绝
3 匹配操作 检查请求的操作是否在Capability的actions列表中

验证代码大概长这样:

function verifyCapability(cap, request) {
  // 1. 验签
  if (!verifySignature(cap)) {
    throw new Error('Capability签名无效');
  }

  // 2. 校验有效期
  if (Date.now() > cap.expires_at) {
    throw new Error('Capability已过期');
  }

  // 3. 匹配操作
  if (!cap.actions.includes(request.action)) {
    throw new Error('操作不被允许');
  }

  // 4. 匹配资源
  if (cap.resource !== request.resource) {
    throw new Error('资源不匹配');
  }

  return true;
}

你想想看,这个流程有什么好处?

  • 无状态:资源服务不需要查数据库,拿着Capability就能验证。性能杠杠的。
  • 可撤销:虽然Capability本身是自包含的,但你可以通过黑名单机制来撤销。比如在Redis里维护一个已撤销Capability的列表。
  • 细粒度:每个Capability只针对一个资源和几个操作,不像角色那样一给就是一大片。

注意:Capability一旦泄露,攻击者就能拿着它为所欲为。所以:

  • 必须使用HTTPS传输
  • Capability中不要包含敏感信息(比如密码)
  • 建议使用短有效期,配合刷新机制

3.4 实际项目中的坑

嗯,这里我要多说两句。我在做第一个RMC项目时,踩过一个坑:Capability的粒度太粗

当时我把一个用户的Capability设计成可以访问「所有订单」。结果这个用户是个客服,只需要查看自己负责的订单。后来一个误操作,他把别人的订单给删了。你说冤不冤?

所以我的建议是:Capability的资源标识一定要精确到实例级别。比如:

  • ❌ 错误:resource: "order:*"
  • ✅ 正确:resource: "order:98765"

还有一个坑:Capability的传递问题。在微服务架构里,服务A调用服务B时,要不要把Capability传过去?

我的做法是:不传递,而是重新签发。服务A拿着自己的Capability去认证服务,申请一个专门给服务B用的Capability。这样每个服务只知道自己该知道的,不会造成权限扩散。

总结一下:Capability认证模型的核心就是「权限跟着令牌走」。生成时精确控制,分发时安全传输,验证时快速高效。记住:最小权限、短有效期、精确资源,这三点做到位了,你的系统安全就稳了一半。


专注资料整理