4. 设备与资产隔离:设备/资产所属租户绑定机制、跨租户数据访问限制、设备凭证管理

在多租户 IoT 平台中,设备与资产是租户的核心数字资源。本章深入剖析 ThingsBoard 如何通过租户绑定机制、跨租户访问限制和凭证管理体系,实现设备与资产的严格隔离,确保每个租户只能操作属于自己的资源。

4.1 设备/资产所属租户绑定机制

ThingsBoard 采用实体-租户强关联模型。每个设备(Device)和资产(Asset)在创建时都必须指定所属租户,且一旦绑定,租户 ID 成为该实体的不可变属性。

4.1.1 绑定原理

  • 实体表结构:设备与资产表均包含 tenant_id 字段,作为外键关联租户表。
  • 创建流程:REST API 或 UI 创建设备/资产时,系统自动从当前登录用户上下文获取租户 ID,写入实体记录。
  • 不可变性:租户 ID 在实体生命周期内不可修改,防止租户间资源转移导致的数据泄露。

4.1.2 绑定方式对比

绑定方式 触发场景 租户来源 安全性
UI 手动创建 租户管理员在仪表盘添加设备 当前登录租户 高
REST API 创建 第三方系统通过 API 注册设备 API 请求中的租户令牌 高(需验证令牌)
批量导入 CSV 文件批量导入设备 文件中指定租户 ID 中(需校验租户存在性)
规则链创建 规则链节点动态创建设备 消息元数据中的租户 ID 中(需防止注入)
最佳实践:生产环境中建议仅允许租户管理员通过 UI 或受控 API 创建设备,避免规则链或批量导入时因租户 ID 错误导致资源归属混乱。

4.2 跨租户数据访问限制

ThingsBoard 通过实体查询过滤器和权限校验层双重机制,确保任何跨租户数据访问都被拦截。

4.2.1 查询层隔离

所有设备/资产查询 API 在服务端自动附加 tenant_id 过滤条件。例如,获取设备列表的 SQL 查询会被改写为:

-- 原始查询(用户视角)
SELECT * FROM device WHERE name LIKE '%sensor%'

-- 实际执行(系统自动注入租户过滤)
SELECT * FROM device 
WHERE tenant_id = 'current_tenant_uuid' 
  AND name LIKE '%sensor%'

4.2.2 权限校验层隔离

ThingsBoard 的权限系统在每次实体操作前执行以下校验:

  1. 租户匹配:操作实体所属租户是否与当前用户租户一致。
  2. 角色权限:用户是否拥有该实体的读/写/删除权限。
  3. 资源范围:操作是否在租户的资源配额内。
关键机制:即使两个租户使用相同的设备名称(如 "温度传感器"),系统也会根据 tenant_id 区分,绝不会出现数据交叉。

4.2.3 跨租户数据访问场景限制

场景 是否允许 说明
租户 A 查看租户 B 的设备列表 ❌ 禁止 API 自动过滤,返回空列表
租户 A 通过设备 ID 直接访问租户 B 的设备 ❌ 禁止 权限校验返回 403 Forbidden
系统管理员查看所有租户设备 ✅ 允许 系统管理员拥有跨租户查询权限
规则链中引用其他租户的设备 ❌ 禁止 规则链执行上下文绑定租户

4.3 设备凭证管理

设备凭证是设备接入平台的身份标识。ThingsBoard 支持多种凭证类型,每种凭证都严格绑定到所属租户。

4.3.1 凭证类型与租户绑定

凭证类型 存储位置 租户绑定方式 典型场景
访问令牌(Access Token) 设备属性表 设备所属租户 轻量级设备接入
X.509 证书 凭证表 + 证书链 证书 CN 字段映射租户 高安全场景
MQTT 基本认证 设备凭证表 用户名/密码关联租户 传统设备接入
JWT 令牌 网关会话 令牌中携带租户 ID 网关代理多设备

4.3.2 凭证生命周期管理

  • 创建:设备创建时自动生成默认凭证(如随机 Access Token),或由管理员手动指定。
  • 轮换:支持定期更换凭证,旧凭证立即失效。
  • 吊销:设备停用时吊销凭证,阻止后续连接。
  • 审计:所有凭证操作记录在审计日志中,包含租户 ID、操作人、时间戳。
安全警告:切勿在代码或配置文件中硬编码设备凭证。建议使用 ThingsBoard 的凭证管理 API 动态获取,或通过环境变量注入。

4.4 设备与资产隔离架构总览

下图展示了设备与资产在租户隔离体系中的完整数据流和权限校验路径:

设备与资产租户隔离架构 租户 A 隔离域 租户 B 隔离域 设备 A1 tenant_id: A 设备 A2 tenant_id: A 资产 A1 tenant_id: A 资产 A2 tenant_id: A 凭证存储(Access Token / 证书) 仅允许租户 A 设备使用 权限校验层 校验 tenant_id + 角色 + 资源配额 设备 B1 tenant_id: B 设备 B2 tenant_id: B 资产 B1 tenant_id: B 资产 B2 tenant_id: B 凭证存储(Access Token / 证书) 仅允许租户 B 设备使用 权限校验层 校验 tenant_id + 角色 + 资源配额 ✕ ✕ ✕ 每个租户拥有独立的设备、资产、凭证存储和权限校验层,跨租户访问被严格禁止

4.5 实战配置示例

4.5.1 通过 REST API 创建设备并绑定租户

POST /api/device
Content-Type: application/json
X-Authorization: Bearer <租户管理员JWT令牌>

{
  "name": "温度传感器-01",
  "type": "temperature_sensor",
  "label": "车间A-温度传感器",
  "additionalInfo": {
    "location": "车间A",
    "installDate": "2025-01-15"
  }
}

// 响应示例(系统自动绑定当前租户)
{
  "id": {
    "id": "d4c3b2a1-...",
    "entityType": "DEVICE"
  },
  "tenantId": {
    "id": "当前租户UUID",
    "entityType": "TENANT"
  },
  "name": "温度传感器-01",
  "type": "temperature_sensor",
  "createdTime": 1736937600000
}

4.5.2 设备凭证轮换操作

// 获取当前设备凭证
GET /api/device/d4c3b2a1-.../credentials
X-Authorization: Bearer <租户管理员JWT令牌>

// 响应
{
  "id": "cred-uuid-...",
  "deviceId": "d4c3b2a1-...",
  "credentialsType": "ACCESS_TOKEN",
  "credentialsId": "old-token-value"
}

// 更新凭证(轮换)
POST /api/device/d4c3b2a1-.../credentials
Content-Type: application/json
X-Authorization: Bearer <租户管理员JWT令牌>

{
  "credentialsType": "ACCESS_TOKEN",
  "credentialsId": "new-token-value-2025"
}

// 响应:200 OK,旧凭证立即失效
凭证轮换建议:建议每 90 天轮换一次设备凭证。轮换期间可保留新旧凭证并行使用 5 分钟,避免设备断连。

4.6 隔离效果验证

完成配置后,可通过以下步骤验证隔离效果:

  1. 使用租户 A 的 JWT 令牌调用 GET /api/tenant/devices,确认只返回租户 A 的设备。
  2. 尝试使用租户 A 的令牌访问租户 B 的设备详情(GET /api/device/<租户B设备ID>),应返回 403 错误。
  3. 使用租户 B 的设备凭证(Access Token)连接 MQTT,确认只能发布/订阅租户 B 的遥测主题。
  4. 检查审计日志,确认所有跨租户访问尝试被记录并拒绝。
核心结论:设备与资产的租户绑定是 ThingsBoard 多租户隔离的基石。通过 tenant_id 的强制绑定、查询层的自动过滤、权限校验层的严格拦截以及凭证的租户级管理,平台能够为每个租户提供独立、安全、可控的设备与资产管理环境。