EMQX客户端认证流程:从连接到授权全解析
引言:认证与授权的核心挑战
在物联网(IoT)和工业物联网(IIoT)场景中,设备与消息服务器之间的安全通信至关重要。EMQX作为最具可扩展性的开源MQTT代理(Message Queue Telemetry Transport,消息队列遥测传输),提供了完善的客户端认证与授权机制。本文将深入解析EMQX客户端从连接请求到权限验证的完整流程,帮助开发者构建安全可靠的MQTT部署。
你将学到
- MQTT协议中认证与授权的核心区别
- EMQX认证链的模块化设计与执行逻辑
- 从TCP握手到PUBLISH权限验证的全流程解析
- 多源授权策略的优先级与冲突解决
- 生产环境中的性能优化与常见问题排查
一、认证与授权的概念框架
1.1 核心定义与区别
| 维度 | 认证(Authentication) | 授权(Authorization) |
|---|---|---|
| 核心目标 | 验证客户端身份合法性 | 验证客户端操作权限范围 |
| 触发时机 | TCP连接建立后,MQTT CONNECT报文处理阶段 | 每次PUBLISH/SUBSCRIBE操作前 |
| 决策依据 | 客户端提供的凭证(用户名/密码/证书等) | 预定义的访问控制规则 |
| 结果类型 | 成功/失败(连接允许/拒绝) | 允许/拒绝/未匹配(操作权限判定) |
| EMQX实现模块 | emqx_auth_*系列认证插件 | emqx_authz_*系列授权插件 |
1.2 EMQX安全架构概览
二、认证流程深度解析
2.1 认证链执行逻辑
EMQX采用可扩展的认证链设计,支持同时配置多种认证方式。认证流程在emqx_auth模块中实现,核心处理函数为handle_authenticate:
%% 伪代码示意
handle_authenticate(ClientInfo, AuthResult) ->
case AuthResult of
ok ->
%% 认证成功,继续处理
{ok, ClientInfo};
{error, Reason} ->
%% 认证失败,拒绝连接
{error, Reason};
ignore ->
%% 忽略当前认证器,尝试下一个
next_authenticator(ClientInfo)
end.
认证器按配置顺序依次执行,直到某个认证器返回明确结果(成功/失败)或所有认证器均返回忽略。
2.2 主流认证方式实现
2.2.1 密码认证(emqx_auth_mnesia)
基于内置Mnesia数据库的密码认证流程:
2.2.2 JWT认证(emqx_auth_jwt)
JSON Web Token(JWT)认证配置示例:
{
"auth.jwt": {
"secret": "your-secret-key",
"pubkey": "/etc/emqx/certs/jwt_public_key.pem",
"verify_claims": {
"exp": ">",
"iat": "<",
"sub": "mqtt_user"
},
"from": "username",
"token_in": "password"
}
}
2.3 认证缓存机制
为减轻后端存储压力,EMQX提供认证结果缓存功能(emqx_auth_cache模块):
%% 缓存实现关键代码
cached_simple_sync_query(CacheName, CacheKey, ResourceID, Query) ->
emqx_auth_cache:with_cache(CacheName, CacheKey, fun() ->
case emqx_resource:simple_sync_query(ResourceID, eval_query(Query)) of
{error, _} = Error ->
{nocache, Error};
Result ->
{cache, Result}
end
end).
默认缓存过期时间为300秒,可通过配置调整:
auth.cache {
enable = true
ttl = 300s
max_size = 32MB
}
三、授权流程深度解析
3.1 授权决策核心逻辑
EMQX授权流程在emqx_authz模块中实现,核心函数authorize/5处理权限验证:
authorize(#{username := Username} = Client, PubSub, Topic, _DefaultResult, SourceStates) ->
case maps:get(is_superuser, Client, false) of
true ->
%% 超级用户直接允许
emqx_metrics:inc(?METRIC_SUPERUSER),
{stop, #{result => allow, from => superuser}};
false ->
authorize_non_superuser(Client, PubSub, Topic, SourceStates)
end.
授权规则按优先级顺序匹配,支持多种授权源组合:
3.2 授权规则语法
EMQX支持两种ACL规则格式,以文件授权(emqx_authz_file)为例:
3.2.1 简单格式
{
"allow": {
"users": ["user1", "user2"],
"topics": ["sensor/+/temp", "actuator/+/cmd"],
"actions": ["publish", "subscribe"]
}
}
3.2.2 高级格式
{
"rules": [
{
"action": "publish",
"permission": "allow",
"username": "device/+/sensor",
"topic": "sensor/${username}/#",
"qos": [0, 1]
},
{
"action": "subscribe",
"permission": "deny",
"username": "#",
"topic": "$SYS/#"
}
]
}
3.3 多源授权优先级
当配置多个授权源时,EMQX按以下顺序处理:
- 客户端信息授权(client_info)
- 文件授权(file)
- 数据库授权(mysql/postgresql/redis等)
- HTTP授权(http)
- 内置默认规则
每个授权源返回结果处理逻辑:
do_authorize(Client, Action, Topic, [SourceState | SourceStates]) ->
case Module:authorize(Client, Action, Topic, SourceState) of
{matched, allow} -> {allow, SourceType};
{matched, deny} -> {deny, SourceType};
nomatch -> do_authorize(Client, Action, Topic, SourceStates);
ignore -> do_authorize(Client, Action, Topic, SourceStates)
end;
do_authorize(_Client, _Action, _Topic, []) ->
nomatch.
四、性能优化与最佳实践
4.1 认证性能优化
| 优化策略 | 实现方法 | 性能提升预期 |
|---|---|---|
| 启用认证缓存 | auth.cache.enable = true | 降低90%后端查询 |
| 使用连接池 | 配置数据库连接池大小 pool_size = 32 | 支持高并发认证 |
| 异步认证处理 | 采用emqx_auth_http异步模式 | 避免阻塞连接建立 |
| 预编译密码哈希 | 预先计算并存储哈希值,避免运行时计算 | 减少CPU占用 |
4.2 授权性能优化
授权规则匹配性能关键指标:
- 规则数量:建议不超过100条
- 通配符使用:避免过多层级的
#通配符 - 规则顺序:将高频匹配规则前置
4.3 常见问题排查
4.3.1 认证失败排查流程
- 检查EMQX日志:
tail -f emqx/log/erlang.log.1 - 启用认证调试:
emqx_ctl log set debug auth - 验证客户端凭证:使用
emqx_ctl users check命令 - 检查认证器顺序:确保优先级正确
4.3.2 授权规则不生效排查
# 查看当前授权配置
emqx_ctl authz show
# 测试特定客户端权限
emqx_ctl authz test user1 publish sensor/temp
五、生产环境配置示例
5.1 MQTT + TLS + JWT认证配置
## emqx.conf
listeners.ssl.default {
bind = "0.0.0.0:8883"
ssl_options {
cacertfile = "/etc/emqx/certs/ca.pem"
certfile = "/etc/emqx/certs/server.pem"
keyfile = "/etc/emqx/certs/server.key"
}
}
auth.jwt {
enable = true
secret = "your-jwt-secret"
from = "username"
token_in = "password"
verify_claims {
exp = ">"
sub = "mqtt_client"
}
}
5.2 多源授权配置
## emqx_authz.conf
authorization {
sources = [
{
type = file
enable = true
path = "/etc/emqx/acl.conf"
},
{
type = mysql
enable = true
database = "mqtt_acl"
username = "root"
password = "password"
server = "127.0.0.1:3306"
query = "SELECT permission, action, topic FROM acl WHERE username = ${username}"
}
]
deny_action = "ignore"
}
六、总结与展望
EMQX提供了企业级的客户端认证与授权解决方案,通过模块化设计和可扩展架构,满足不同场景下的安全需求。随着物联网设备数量激增,EMQX将持续优化认证授权性能,未来版本将重点提升:
- 分布式认证缓存同步
- 基于属性的细粒度授权(ABAC)
- OAuth2.0/OpenID Connect集成
- 实时权限更新机制
掌握EMQX安全机制不仅能保障物联网平台的通信安全,更能为构建大规模设备管理系统提供坚实基础。建议开发者结合具体业务场景,选择合适的认证授权组合,并遵循最小权限原则配置访问控制规则。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



