使用 MongoDB 进行密码认证

作为密码认证方式的一种,EMQX 支持通过集成 MongoDB 进行密码认证,目前 EMQX 支持单节点Replica Set使用 MongoDB 进行密码认证 - 图1 (opens new window)Sharding使用 MongoDB 进行密码认证 - 图2 (opens new window) 三种模式部署的 MongoDB 服务器。

前置准备:

数据结构与查询语句

MongoDB 认证器支持将认证数据存储为 MongoDB 文档。用户需要提供一个查询语句模板,且确保查询结果包含以下字段:

  • password_hash: 必需,数据库中的明文或散列密码字段,可以设置为其他字段名
  • salt: 可选,为空或不存在时视为空盐(salt = ""),可以设置为其他字段名
  • is_superuser: 可选,标记当前客户端是否为超级用户,默认为 false,可以设置为其他字段名

添加用户名为 emqx_u、密码为 public、盐值为 slat_foo123、散列方式为 sha256 且超级用户标志为 true 的用户示例:

  1. > db.mqtt_user.insertOne(
  2. {
  3. "username": "emqx_u",
  4. "salt": "slat_foo123",
  5. "is_superuser": true,
  6. "password_hash": "44edc2d57cde8d79c98145003e105b90a14f1460b79186ea9cfe83942fc5abb5"
  7. }
  8. );
  9. {
  10. "acknowledged" : true,
  11. "insertedId" : ObjectId("631989e20a33e26b05b15abe")
  12. }

提示

当系统中有大量用户时,请确保查询使用的集合已优化并使用有效的索引,以提升大量连接时的数据查找速度并降低 EMQX 负载。

对应的配置参数为:

  • 密码加密方式:sha256
  • 加盐方式:suffix
  • Collection:mqtt_user
  • 查询 Filter:{ username = "${username}" }
  • Password Hash 字段名:password_hash
  • Salt 字段名:salt
  • is_superuser_field: is_superuser

通过 Dashboard 配置

EMQX Dashboard使用 MongoDB 进行密码认证 - 图3 (opens new window) 页面,点击左侧导航栏的访问控制 -> 认证,在随即打开的认证页面,单击创建,依次选择认证方式Password-Based数据源MongoDB,进入配置参数页签:

use mongodb to authenticate

您可根据如下说明完成相关配置:

连接:在此部分完成到 MongoDB 数据库的连接设置。

  • 部署模式:选择 MongoDB 数据库的部署模式,可选值:单节点Replica SetSharding
  • 服务列表):填入 MongoDB 服务器地址 (host:port) ;当部署模式选为 Replica SetSharding 时,您需在此提供所有相关 MongoDB 服务器的地址,不同地址之间以 , 分隔,格式为 host1:port1,host2:port2,...
  • Replica Set Name:字符串,用于指定 Replica Set 的名称,仅需在部署模式设置为 Replica Set 时设置。
  • 数据库:数据库名称。
  • Collection: MongoDB 集合名称。
  • 用户名(可选):填入用户名。
  • 密码(可选):填入认证密码。
  • 读模式(可选):读取模式,可选值:master、slave_ok;默认值:mastermaster 意味着序列中的每个查询都必须从主服务器读取新数据。 如果连接的服务器不是主服务器,则第一次读取将失败,其余操作将中止。slave_ok 表示允许每个查询从从服务器读取陈旧数据(来自主服务器的新数据也可以);仅需在部署模式设置为 Replica Set 时设置。
  • 写模式(可选):写入模式, 可选值:unsafesafe;默认值:safe。仅需在部署模式设置为 Replica Set 时设置。

TLS 配置:配置是否启用 TLS。

连接配置:在此部分设置并发连接以及连接超时等待时间。

  • Pool size(可选):填入一个整数用于指定从 EMQX 节点到 MongoDB 数据库的并发连接数;默认值:8
  • 连接超时(可选):填入连接超时等待时长,可选单位:小时分钟毫秒

认证配置:在此部分进行认证加密算法相关的配置。

  • Password Hash 字段名:指定密码的字段名称。
  • 密码加密方式:选择存储密码时使用的散列算法,如 plain、md5、sha、bcrypt、pbkdf2 等。
    • 选择 plainmd5shasha256sha512 算法,需配置:
      • 加盐方式:用于指定盐和密码的组合方式,除需将访问凭据从外部存储迁移到 EMQX 内置数据库中外,一般不需要更改此选项;可选值:suffix(在密码尾部加盐)、prefix(在密码头部加盐)、disable(不启用)。注意:如选择 plain,加盐方式应设为 disable
    • 选择 bcrypt 算法,需配置:
    • Salt Rounds:指定散列需要的计算次数(2^Salt Rounds),也称成本因子。默认值:10,可选值:4~31;数值越高,加密的安全性越高,因此建议采用较大的值,但相应的用户验证的耗时也会增加,您可根据业务需求进行配置。
    • 选择 pkbdf2 算法,需配置:
    • 伪随机函数:指定生成密钥使用的散列函数,如 sha256 等。
    • 迭代次数:指定散列次数,默认值:4096
    • 密钥长度(可选):指定希望得到的密钥长度。如不指定,密钥长度将由伪随机函数确定。
  • is_superuser 字段名:指定 MongoDB 数据中超级用户标志位字段。
  • salt 字段名:指定 MongoDB 数据中盐的字段。
  • 查询 Filter:MongoDB filter,用于过滤数据,支持认证占位符

点击创建完成相关配置。

通过配置文件配置

您也可以通过配置文件完成相关配置,关于 单节点、ReplicaSet 和 Sharding 的详细配置方式,可参考:

以下为各部署模式下的配置文件示例:

  1. {
  2. mechanism = password_based
  3. backend = mongodb
  4. enable = true
  5. password_hash_algorithm {
  6. name = sha256
  7. salt_position = suffix
  8. }
  9. collection = "mqtt_user"
  10. filter { username = "${username}" }
  11. mongo_type = single
  12. server = "127.0.0.1:27017"
  13. database = "mqtt"
  14. username = "emqx"
  15. password = "secret"
  16. }
  1. {
  2. mechanism = password_based
  3. backend = mongodb
  4. enable = true
  5. password_hash_algorithm {
  6. name = sha256
  7. salt_position = suffix
  8. }
  9. collection = "mqtt_user"
  10. filter { username = "${username}" }
  11. mongo_type = rs
  12. servers = "10.123.12.10:27017,10.123.12.11:27017,10.123.12.12:27017"
  13. replica_set_name = "rs0"
  14. database = "mqtt"
  15. username = "emqx"
  16. password = "secret"
  17. }
  1. {
  2. mechanism = password_based
  3. backend = mongodb
  4. enable = true
  5. password_hash_algorithm {
  6. name = sha256
  7. salt_position = suffix
  8. }
  9. collection = "mqtt_user"
  10. filter { username = "${username}" }
  11. mongo_type = sharded
  12. servers = "10.123.12.10:27017,10.123.12.11:27017,10.123.12.12:27017"
  13. database = "mqtt"
  14. username = "emqx"
  15. password = "secret"
  16. }