与其他ThingsBoard系列产品一样,TBMQ使用JWT(JSON Web Tokens)在API客户端(如浏览器和脚本)与平台之间安全地传递声明。 JWT令牌作为安全信息交换机制。用户登录时,其凭据被交换为一对JWT令牌: 访问令牌用于API调用认证,刷新令牌用于在原令牌过期后获取新的访问令牌。 这些令牌包含用户身份和权限的关键信息,实现与平台的安全通信。 更多信息请参阅管理REST API文档。
从2.2.0版本开始,TBMQ还支持基于JWT的MQTT客户端认证,作为可插拔MQTT认证提供者之一。 这实现了安全、灵活且可扩展的身份验证,无需依赖用户名或密码等静态凭据。 客户端提交包含所有必要认证信息的签名令牌,支持与集中式身份系统集成,提升整体安全性。
JWT认证概述
当客户端使用JWT令牌连接时,TBMQ会执行多步验证流程以验证令牌、检查其声明并确定客户端的权限。
客户端在MQTT CONNECT报文的password字段中包含签名JWT令牌。
TBMQ使用已配置的验证器(基于HMAC、PEM或JWKS)验证令牌的签名。若签名有效,代理继续检查令牌的声明。它验证:- exp(过期时间)声明以确保令牌未过期- nbf(生效时间)声明以确保令牌当前有效
还可配置自定义声明验证——例如要求特定声明与客户端的username或clientId匹配。
TBMQ还支持从令牌声明中提取基于角色的授权模式和客户端类型。
这些值决定客户端的类型(例如DEVICE或APPLICATION)以及允许发布或订阅的主题。
仅当签名有效且所有必需声明通过验证时,客户端才被授予访问权限。
配置提供者
MQTT客户端的JWT认证通过TBMQ用户界面配置。 本节说明如何配置签名验证、定义可选认证声明校验、设置动态客户端类型分类以及管理授权规则。配置完成后, 可启用提供者以开始使用JWT令牌认证客户端。
签名验证
签名验证机制决定TBMQ如何验证JWT令牌的签名, 以确保令牌由受信任的权威机构签发且未被篡改。有两种选项:- 基于算法(HMAC或PEM)——使用预配置的密钥或公钥验证传入令牌。- JWKS(JSON Web Key Set)——从远程JWKS端点动态获取公钥列表。 常用于发布密钥集的身份平台(如Auth0、AWS Cognito、Keycloak)。
基于HMAC
HMAC是一种对称算法,使用同一密钥进行JWT的签名和验证。 常用于内部系统或由你控制的可信服务签发令牌的场景。
支持所有JWT标准HMAC算法:HS256、HS384、HS512。密钥应与签发令牌时使用的一致。
公钥(PEM)
当JWT使用非对称私钥签名时,可选此方法。 TBMQ将使用对应的PEM格式公钥验证签名。
支持的密钥类型:RSA、EC和Ed25519。请确保上传的公钥与签发JWT的私钥匹配。
JWKS
JWKS(JSON Web Key Set)允许TBMQ从远程端点获取公钥列表。 当使用自动轮换签名密钥的身份提供者时特别有用。 TBMQ会定期从端点下载和缓存密钥,用于验证传入令牌。
JWT声明与访问控制流程
JWT令牌成功验证后,TBMQ执行多阶段验证和分类流程, 确定客户端是否允许连接、如何标识以及可访问哪些主题。
标准声明验证
首先,TBMQ检查JWT中嵌入的几个标准声明:- exp(过期时间)声明以确保令牌未过期- nbf(生效时间)声明以确保令牌当前有效
若令牌已过期或尚未生效,客户端连接将立即被拒绝。 这些检查自动进行,无需任何配置。
认证声明(可选)
可定义自定义声明验证规则作为键值对,每对包含:- Claim——JWT中的声明名称- Value——用于比对的期望值
若列表中任何声明与令牌中的实际值不匹配,客户端认证将失败——即使令牌签名有效。
为支持动态检查,可使用${username}和${clientId}等占位符。
这些占位符会在连接时解析为MQTT客户端的username或client ID。
此机制通过确保JWT不仅有效且确实是为发起请求的特定MQTT客户端签发的,增加了额外的安全层。
为更好理解自定义认证声明的工作方式,请参考以下示例。
配置了三个自定义声明用于验证:- sub = ${clientId}——确保令牌主体与MQTT client ID匹配- mqtt_user = ${username}——确保令牌是为正确的MQTT username签发的- env = prod——强制令牌仅在生产环境中有效
若任何条件不满足,认证尝试将被拒绝。
一个MQTT客户端以username = thermostat-007和client ID = client-007连接。
同时password字段中的JWT包含以下声明:
1
2
3
4
5
{
"sub": "client-007",
"mqtt_user": "thermostat-007",
"env": "prod"
}
在此情况下:- sub必须匹配client ID- mqtt_user必须匹配username- env必须精确为prod
若所有条件满足,客户端将通过认证。若任何条件不满足,连接将被拒绝。
客户端类型配置(可选)
此部分配置broker在认证时如何确定客户端类型,可为DEVICE或APPLICATION。
默认情况下,所有客户端被分配为通过”Device / Application”开关选择的类型。 可选择定义一个或多个声明条件。若所有条件匹配,TBMQ将分配相反的客户端类型。 这允许在认证过程中动态分类客户端。
为更好理解动态客户端类型分类的工作方式,请参考以下示例。
客户端类型默认设为DEVICE。
配置中还定义了一个自定义声明role,期望值为app用于比对。
如果MQTT客户端连接时password字段中的JWT包含此声明且值为app,该MQTT客户端将被归类为APPLICATION。
授权
客户端成功通过验证和分类步骤后,TBMQ应用主题级授权规则, 确定客户端允许发布和订阅的主题。
对于基于JWT的客户端,TBMQ支持两层基于正则表达式的授权规则:- 默认授权规则——在提供者设置中手动配置的主题模式集合。- 动态授权规则——运行时从JWT声明中提取的主题模式列表(如已配置)。
可分别为发布和订阅定义默认主题模式。这些模式使用正则表达式且始终必填。 它们也在动态模式未配置或无法应用时作为备选。
正则过滤器示例:- 允许特定主题——规则country/.*仅允许客户端向以country/开头的主题发布/订阅。- 允许任何主题——规则.*(默认)允许客户端向任何主题发布/订阅。- 禁止所有主题——若规则为空,客户端禁止发布/订阅。
要启用动态授权,请指定包含发布和/或订阅主题模式的JWT声明名称(如pub_rules、sub_rules)。 配置后,TBMQ将尝试从这些声明中提取主题模式列表,并将其作为客户端的有效授权规则。
若声明缺失或格式错误,TBMQ会优雅地回退到该方向的默认规则。 此回退行为对发布和订阅独立生效。可对其中一个使用动态规则,另一个使用默认规则。
为更好理解默认和动态授权规则如何协同工作,请参考以下示例。
默认和动态授权规则配置如下:
客户端使用包含以下声明的JWT连接:
1
2
3
4
{
"pub_rules": ["devices/.*/data"],
"sub_rules": ["sensors/.*", "alerts/.*"]
}
In this case:- pub_rules声明覆盖默认发布规则,限制仅访问devices/.*/data。- sub_rules声明通过额外允许alerts/.*来扩展默认订阅规则。
这展示了如何使用动态规则为每个客户端自定义访问权限,同时在需要时提供可靠的备选方案。
启用并保存提供者
完成配置后,务必在提供者配置页面顶部切换”Enable provider”开关以启用JWT认证提供者。 然后点击”Apply changes”按钮保存配置。
启用后,此提供者将用于认证连接时在password字段中包含JWT令牌的任何MQTT客户端。
基于HMAC算法的MQTT示例
你需要拥有一个有效的JWT令牌,也可以使用任何支持HS256签名的语言生成。以下是一个简单的Python示例。
将以下脚本保存为generate_jwt.py并在本机运行。
运行脚本:
1
python3 generate_jwt.py
示例输出:
1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
可以使用jwt.io验证令牌的声明和签名。
以下是使用mosquitto_pub客户端通过无TLS的普通MQTT进行JWT认证发布消息的示例:
1
mosquitto_pub -d -q 1 -h "YOUR_TBMQ_HOST" -p "1883" -t "sensors/temperature" -i "YOUR_CLIENT_ID" -P "YOUR_JWT_TOKEN" -m {"temperature":25} -V 5
说明:
- YOUR_TBMQ_HOST——TBMQ实例的主机名或IP。
- YOUR_CLIENT_ID——你的客户端ID。在此示例中,应等于”mqtt-client-id”以通过JWT提供者中_sub=${clientId}_的认证声明检查。
- YOUR_JWT_TOKEN——使用上述Python脚本生成的令牌。
基于HMAC算法的MQTTS示例
单向TLS确保客户端使用服务器证书验证服务器身份。 请按照MQTT over SSL指南为TBMQ配置服务器证书。
以下是通过MQTTS(TLS)使用JWT认证连接的示例:
1
mosquitto_pub -d -q 1 --cafile YOUR_PEM_FILE -h "YOUR_TBMQ_HOST" -p 8883 -t "sensors/temperature" -i "YOUR_CLIENT_ID" -P "YOUR_JWT_TOKEN" -m {"temperature":25} -V 5
说明:
- YOUR_PEM_FILE——CA证书文件的路径。
- YOUR_TBMQ_HOST——TBMQ实例的主机名或IP。
- YOUR_CLIENT_ID——必须与JWT负载中的
sub声明匹配。 - YOUR_JWT_TOKEN——之前生成的令牌。
下一步
-
快速入门指南 - 本指南提供 TBMQ 的快速概览。
-
安装指南 - 学习如何使用 Docker 配置 TBMQ 或在 AWS、GCP、Azure 的 K8S 环境中部署。
-
配置指南 - 了解 TBMQ 配置文件和参数。
-
MQTT 客户端类型指南 - 了解 TBMQ 客户端类型。
-
与 ThingsBoard 集成 - 了解如何将 TBMQ 与 ThingsBoard 集成。