关于ACL鉴权的疑问

就拿Mysql的acl鉴权来说
主题$abc/234/klm只能让use1用户来订阅,SQL要怎么写?

我的想法:

//禁止所有用户订阅$abc/打头的主题

INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`) VALUES (15883698888683139, 0, '', 'use1', '', 3, '$abc/#');

//允许use1订阅

INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`) VALUES (1511369077660683138, 1, '', 'use1', '', 3, '$abc/234/klm');

这样不行呀?怎么搞

image



MySQL | EMQX 5.0 文档
我根据官方文档这么写的,经过测试行的通,两个客户端订阅相同topic,正常客户端接收到的有7条信息,被屏蔽客户端没有接收到,但是控制台上并没有显示,有大佬解答一下吗??

你好,通常我们不建议客户端或应用使用 $ 开头的主题。

你可以插入以下数据来实现你的需要:

INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`) VALUES (15883698888683139, 1, '', 'use1', '', 3, '$abc/#');

INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`) VALUES (15883698888683140, 0, '', '$all', '', 3, '$abc/#');

请注意插入的顺序,因为查询得到的规则顺序是由插入顺序决定的,所以需要保证 use1 优先匹配到允许订阅的那条规则。

同时你还需要修改查询语句,示例:

query = "SELECT permission, action, topic FROM mqtt_acl WHERE username = ${username}" or username = '$all'

$all 只是一个推荐值,你也可以改为 all 等等,只要确保与表中数据一致并且不会与正常的 username 重复即可。

以上只是一种实现方式。需要注意的是,当你添加了很多条这样的通用规则时,那么每次进行鉴权都会获取到这些规则并挨个进行匹配,这可能会对鉴权性能带来明显的影响。

所以更建议你使用另一种方式,MySQL 表中定义针对具体客户端的定向规则,然后将鉴权配置中的 no_match 设置为 deny,这样所有不匹配规则的操作都会被拒绝。

no_match 的文档可参考:简介 | EMQX 5.0 文档