数据面授权策略说明

最近更新时间:2025-03-26 11:53:42

我的收藏

基本概念

授权是指对 MQTT 客户端的连接(CONNECT)、 发布(PUBLISH)和订阅(SUBSCRIBE)操作进行权限控制。当 MQTT 客户端连接,发布或者订阅时,MQTT 服务端查询授权数据源,将查询到的访问控制规则与要执行的操作进行匹配,根据匹配结果确定允许或者拒绝本次操作。
访问控制语句逻辑上由 Access、Actions,、Topics 和 Condition 4 部分组成。
领域
字段名称
示例值
必填
决策
effect
allow/deny
操作
actions
["connect", "pub", "sub"]
资源
topics
["home/room1/*", "sensor/temperature/0"]
条件
clientId
"sensor*"
username
"user*"
qos
[0, 1, 2]
retain
true/false
ip
客户端IP地址: 10.0.0.1 or CIDR 10.0.0.0/16
MQTT 实例默认提供基于数据库的策略存储源,可通过控制台或者云 API 定义、更新、排序、删除策略。策略修改变更定期同步到 MQTT 节点后生效。

工作原理

授权链

除了内置的基于数据库的访问控制源,也支持基于JWT claim定义ACL。多个授权器共同组成一个授权器链。当客户端执行操作时,按照授权器链先后进行匹配,直到获取决策结果。

每一个授权器内可定义0或多条授权策略,授权器按照定义的先后顺序,依次根据当前客户端操作(Actions)、操作资源(Topics)、以及客户端本身信息(Client ID、Username、证书信息)与策略规则进行匹配。
当授权器的某一条策略规则匹配时,根据规则的决策,允许或者拒绝客户端操作,授权器链匹配结束。
当策略规则不匹配时,尝试匹配该授权器内定义的下一条规则。
当该授权器所有规则都不匹配时,交由下一个授权器进行匹配。
当所有授权器都匹配结束仍未配到规则,默认拒绝客户端请求。

策略变量

Topic、ClientId、Username 支持以下策略变量,当授权器执行匹配操作时,会将 ${PolicyVariable} 替换成真实值后再进行匹配。
变量名/PolicyVariable
语义
Username
MQTT 客户端连接 Username。
ClientId
MQTT Client ID。
Certificate.Subject.Country
一机一证场景下证书国家信息,详细参见 RFC4519
Certificate.Subject.Organization
一机一证场景下证书组织信息,详细参见 RFC4519
Certificate.Subject.OrganizationalUnit
一机一证场景下证书组织单元信息,详细参见 RFC4519
Certificate.Subject.State
一机一证场景下证书省、直辖市信息,详细参见 RFC4519
Certificate.Subject.CommonName
一机一证场景下证书CommonName,详细参见 RFC4519
Certificate.Subject.SerialNumber
一机一证场景下证书序列号,详细参见 RFC4519

策略通配符

Topics 字段

Topics字段支持下列通配符
通配符/Wildcard
语义
+
与 MQTT 协议 Topic Filter Wildcard 一致。
#
与 MQTT 协议 Topic Filter Wildcard 一致。
?
任何一个字符。
*
任意个字符。

ClientId、Username 字段

通配符/Wildcard
语义
?
任何一个字符。
*
任意个字符。

策略缓存

根据授权器的特性,MQTT 服务器可能会对策略规则进行缓存以加快获取策略速度。 因此,通过控制台或者云 API 变更的策略需要等待缓存更新后才能生效。

策略顺序

策略顺序会影响授权器链的最终结果,当定义多条策略规则时,请确认授权顺序符合业务要求。

策略示例

允许所有客户端操作


{
"effect": "allow",
"actions": [
"connect",
"pub",
"sub"
],
"topics": [
"*"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

拒绝所有客户端操作


{
"effect": "deny",
"actions": [
"connect",
"pub",
"sub"
],
"topics": [
"*"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

允许所有客户端发布消息到一个 Topic

{
"effect": "allow",
"actions": [
"connect",
"pub"
],
"topics": [
"topicA/test"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

允许所有客户端发布消息到多个 Topic

{
"effect": "allow",
"actions": [
"connect",
"pub"
],
"topics": [
"home/sensor", "device/1"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

允许客户端发送到任意子 Topic

{
"effect": "allow",
"actions": [
"connect",
"pub"
],
"topics": [
"home/#", "device/+"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

允许客户端发送到指定前缀、后缀 Topic

{
"effect": "allow",
"actions": [
"connect",
"pub"
],
"topics": [
"prefix*", "*suffix"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

允许 client-Id 包含 username 的 client 连接

{
"effect": "allow",
"actions": [
"connect"
],
"topics": [
"*"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "*${Username}*",
"username": "",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

拒绝 username 中包含 root 的客户端连接

{
"effect": "deny",
"actions": [
"connect"
],
"topics": [
"*"
],
"condition": {
"ip": "0.0.0.0/0",
"clientId": "*",
"username": "*root*",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

仅允许客户端 IP 在指定网段订阅消息

{
"effect": "allow",
"actions": [
"connect", "sub"
],
"topics": [
"*"
],
"condition": {
"ip": "192.168.0.0/16",
"clientId": "*",
"username": "*",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

客户端ClientId与BYOC证书CommonName匹配的客户端允许发送订阅特定消息

{
"effect": "allow",
"actions": [
"connect", "pub", "sub"
],
"topics": [
"home/${Username}/+", "sensor/${ClientId}/#"
],
"condition": {
"ip": "192.168.0.0/16",
"clientId": "*${Certificate.Subject.CommonName}*",
"username": "*",
"qos": [
0,
1,
2
],
"retain": [
"true",
"false"
]
}
}

操作步骤

1. 登录 MQTT 控制台
2. 在左侧导航栏单击资源管理 > 集群管理,选择好地域后,单击目标集群的“ID”,进入集群基本信息页面。
3. 在集群详情页,选择授权策略管理页签,单击新建策略,填写策略信息。
策略名称:3-64个字符,支持中文、字母、数字、“-”及“_”。
描述:选填,不得超过128个字符。
创建方式:同时支持可视化的策略配置和 JSON 文件配置。
效果(Effect):“允许” 或者 “拒绝” 二者选一,若选择 “允许”,则表示满足配置的以下条件时,客户端的操作可以进行,若选择 “拒绝”,即满足配置的以下条件时,客户端的操作将被拒绝。
操作:授权策略针对的不同的请求,包含连接(CONNECT),发送消息(PUBLISH)和 订阅消息(SUBSCRIBE),支持多选。
Topic:支持使用通配符和策略变量。
用户名:选填,填写单个用户名或单条资源表达式,支持使用通配符和策略变量,为空表示支持所有用户名。
客户端 ID:选填,填写单条资源表达式,支持使用通配符和策略变量,为空或者 * 表示支持所有客户端。
IP 地址:选填,仅支持填写单个 IP(如 192.168.0.1)或 CIDR 格式(如 192.168.1.0/24)。
QoS:选择授权策略支持的 QoS 等级。
保留消息:选择授权策略是否支持保留消息(retain message)和非保留消息。



4. 单击创建策略,在弹窗中二次确定后完成创建,返回授权策略列表页。
5. 在策略列表页,可以手动调整策略鉴权顺序,服务端会按照当前的策略顺序进行鉴权,如果策略配置冲突,以排序更高的为准。