在 EMQ X Broker 中可以通过配置 ACL(Access Control List,访问控制列表) 来实现。EMQ X 提供了多种 ACL 插件机制,其中最常用、也最适合企业级使用的方案是:基于 HTTP 的外部鉴权接口(emqx_auth_http
/ emqx_acl_http
)。
一、目标
- 客户端连接 MQTT Broker 时,先进行用户名/密码认证;
- 客户端尝试订阅或发布某个主题时,Broker 向外部服务发起请求;
- 外部服务根据业务逻辑判断是否允许该操作;
- 只有授权通过的客户端才能订阅或发布指定主题;
二、交互流程
三、配置步骤
1. 启用插件
emqx_ctl plugins load emqx_auth_http
emqx_ctl plugins load emqx_acl_http
2. 修改配置文件
编辑《认证配置-控制用户登录》 etc/plugins/emqx_auth_http.conf
文件,配置如下内容:
# 用户认证请求地址
auth.http.auth_req = http://my-auth-server/auth/login
# 请求方法
auth.http.auth_req.method = post
# 发送参数(clientid=%c, username=%u, password=%P)
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
编辑《鉴权配置-主题访问控制》
# ACL 鉴权请求地址
auth.http.acl_req = http://my-auth-server/auth/acl
# 请求方法
auth.http.acl_req.method = post
# 参数:
# %A: access 类型 (1=订阅, 2=发布)
# %u: username
# %c: clientid
# %t: topic
auth.http.acl_req.params = access=%A,username=%u,clientid=%c,topic=%t
3. 实现外部鉴权服务(关键部分)
你需要在自己的后端服务中提供两个接口:
接口1:用户认证接口 /auth/login
- 如果返回
"result": true
,表示认证成功; - 如果返回
"result": false
,则拒绝连接。
返回示例(JSON):
{
"result": true,
"msg": "ok"
}
接口2:主题权限接口 /auth/acl
access=1
表示订阅操作;access=2
表示发布操作;
返回示例(JSON):
{
"result": true,
"msg": "ok"
}
- 如果返回
"result": true
,表示允许访问; - 如果返回
"result": false
,则禁止访问。
Java代码示例:
@PostMapping("/auth/acl")
public Map<String, Object> checkAcl(
@RequestParam String username,
@RequestParam String topic,
@RequestParam int access) {
// 数据库查出用户的主题权限
String allowedTopic = getUserAllowedTopic(username);
// 实现通配符匹配逻辑
boolean isMatch = matchTopic(allowedTopic, topic);
Map<String, Object> result = new HashMap<>();
if (isMatch) {
result.put("result", true);
} else {
result.put("result", false);
result.put("msg", "Permission denied");
}
return result;
}