Java-164 MongoDB 认证与权限实战:单实例与分片集群 整体认证配置实战 最小化授权/错误速查/回滚剧本
TL;DR
- 场景:把 MongoDB 从“裸奔”切到最小权限,覆盖单实例 + 分片集群的认证与授权落地。
- 结论:正确顺序=本机创建 root@admin → 开启 authorization → 按库分权(read/readWrite/dbOwner);分片用 KeyFile 做组件间认证,在 mongos 上统一建用户。10 分钟跑通,提供可回滚路径。
- 产出:MRE 脚本、mongodb.conf 模板、角色授予清单、报错速查卡、回滚剧本;适配 MongoDB 7.0/8.0,示例使用 mongosh + URI(含 ?authSource)。

认证流程
创建 wzk_test1 数据库并创建了两个用户,zhangsan用户拥有读写权限,lisi用户拥有只读权限,测试这两个账户的权限。
这里需要以管理员登录测试权限。
创建管理员
MongoDB 安全认证机制详解
管理员账号的必要性
在开启 MongoDB 安全检查前,必须先在 admin 数据库中创建至少一个管理员账号。admin 数据库中的用户拥有特殊权限,能够执行管理操作和访问所有数据库。这些用户被视为全局管理员,对整个 MongoDB 实例拥有最高权限。
身份验证机制的工作原理
MongoDB 的身份验证机制遵循以下原则:
- admin 数据库优先:当启用身份验证时,MongoDB 首先会检查 admin 数据库中是否存在用户账号
- 权限继承机制:如果 admin 数据库为空,即使其他数据库(如 test、production)中存在用户账号,身份验证也不会完全生效
- 超级权限漏洞:当 admin 数据库为空时,客户端可以不提供任何认证信息就能获得完全的读写权限,这会使安全检查形同虚设
安全配置的正确步骤
为确保安全认证有效,应按以下顺序操作:
- 首先在 admin 数据库创建管理员账号:
use admin
db.createUser({user: "adminUser",pwd: "securePassword",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]}
)
- 重启 MongoDB 服务并启用身份验证:
mongod --auth
- 连接时必须提供认证信息:
mongo -u adminUser -p securePassword --authenticationDatabase admin
实际应用场景示例
在企业环境中,通常会配置:
- 1-2 个具有
userAdminAnyDatabase角色的超级管理员账号 - 针对具体应用创建专门的数据库用户,限制其权限范围
- 定期轮换密码和检查权限分配
这种分层安全架构既能保证管理需要,又能遵循最小权限原则。
创建普通用户
如下所示 wzk_test1 是自己新建的新建库,没安全认证之前可以随意 CRUD,其余的都是 MongoDB 自带的数据库。

为 admin 库创建管理员之后,现在来为普通数据库创建普通用户,以 mydb1 为例,方式与创建管理员一致,切换到指定数据库进行创建即可。
为 wzk_test1 数据库创建了两个用户,zhangsan 拥有读写权限,lisi 拥有只读权限,密码123456
use wzk_test1db.createUser({user:"zhangsan",pwd:"123456",roles:[{role:"readWrite",db:"wzk_test1"}]
})db.createUser({user:"lisi",pwd:"123456",roles:[{role:"read",db:"wzk_test1"}]
})

接着从客户端关闭 MongoDB 服务端,之后服务端会以安全认证方式启动。
use admin
db.shutdownServer()
也可以重新后台上杀掉服务再重启也OK的。
别忘了启动的时候,配置里边的 auth 是 true
dbpath=/data/db/
port=27000
bind_ip=0.0.0.0
fork=true
logpath = /data/db/MongoDB.log
logappend = true
auth=true
启动服务:
./mongod -f mongodb.conf
验证权限
普通用户现在仍然可以像之前一样通过命令行客户端连接到 MongoDB 数据库实例,例如使用以下命令直接登录到 wzk_test1 数据库:
mongo 127.0.0.1:27017/wzk_test1 -u username -p password
虽然登录过程本身是成功的(系统不会拒绝连接),但在登录后用户会立即遇到诸多操作限制。具体表现为:
- 系统日志输出明显减少,不再显示完整的操作日志信息
- 尝试执行基础查询命令时会遇到权限不足的错误:
show dbs命令失败 - 无法查看数据库列表show tables命令失败 - 无法查看集合列表- 即使访问那些不需要安全认证的数据库也会操作失败
这种限制的根本原因是 MongoDB 的访问控制机制在起作用。系统会严格遵循"最小权限原则",每个用户只能在自己的权限范围内进行操作。
正确的操作流程应该是:
- 先建立数据库连接
- 然后立即执行授权认证:
db.auth("username", "password")
- 只有认证通过后,才能执行权限范围内的操作
例如,一个只有wzk_test1数据库读写权限的用户:
- 可以正常查询wzk_test1中的集合数据
- 可以创建/删除该库中的集合
- 但无法查看其他数据库信息
- 也不能执行任何数据库管理命令
这种设计确保了数据库的安全性,防止了权限越界操作。在实际应用中,DBA需要根据业务需求,通过db.grantRolesToUser()等方法精确地为每个用户配置适当的权限范围。
分片集群认证
PS:开启安全认证之前,进入路由创建管理员和普通用户
关闭所有配置
这里需要关闭所有的配置节点、分片节点、路由节点
killall mongod
生成秘钥
生成一个秘钥文件,并修改权限
openssl rand -base64 756 > testKeyFile.file
chmod 600 testKeyFile.file

配置秘钥
配置节点集群和分片节点集群,开启认证和指定秘钥文件:
auth=true
keyFile=testKeyFile.file
在路由配置文件中,设置秘钥文件:
keyFile=testKeyFile.file
启动服务
启动所有配置节点、分片节点、路由节点,使用路由进行权限验证。
./mongod -f config/config-17017.conf
./mongod -f config/config-17018.conf
./mongod -f config/config-17019.conf
./mongod -f shard/shard1/shard1-37017.conf
./mongod -f shard/shard1/shard1-37018.conf
./mongod -f shard/shard1/shard1-37019.conf
./mongod -f shard/shard2/shard2-47017.conf
./mongod -f shard/shard2/shard2-47018.conf
./mongod -f shard/shard2/shard2-47019.conf
./mongos -f route/route-27017.conf
最小化可运行
准备配置
mongodb.conf(最小模板):
storage:dbPath: /data/db
systemLog:destination: filepath: /data/db/mongodb.loglogAppend: true
net:bindIp: 0.0.0.0port: 27017
processManagement:fork: true
# 第一次先不要开启 authorization,创建好用户再启用
# security:
# authorization: enabled
启动:
mongod -f mongodb.conf
创建首个管理员(admin 库)
通过 mongosh 连接本机(触发 localhost 例外,仅用于创建首个用户)。
// 连接
mongosh --host 127.0.0.1 --port 27017use admindb.createUser({user: 'adminUser',pwd: '强密码_建议16+位',roles: [ { role: 'root', db: 'admin' } ]
})
说明:相较 userAdminAnyDatabase,root 更贴合超管需求;若公司有分权要求,可拆分多个管理员角色。
启用授权并重启
编辑 mongodb.conf:
security:authorization: enabled
重启:
mongod --shutdown --config mongodb.conf || true
mongod -f mongodb.conf
创建业务库与用户
mongosh -u adminUser -p '强密码_建议16+位' --authenticationDatabase admin \--host 127.0.0.1 --port 27017use wzk_test1db.createUser({user: 'zhangsan',pwd: '建议强密码',roles: [ { role: 'readWrite', db: 'wzk_test1' } ]
})db.createUser({user: 'lisi',pwd: '建议强密码',roles: [ { role: 'read', db: 'wzk_test1' } ]
})
权限验证
只读用户 lisi:
mongosh 'mongodb://lisi:密码@127.0.0.1:27017/wzk_test1?authSource=wzk_test1'
// 允许:查询
use wzk_test1db.collection('demo').findOne()// 拒绝:写入(返回 Unauthorized error 13)
db.collection('demo').insertOne({a:1})
读写用户 zhangsan:
mongosh 'mongodb://zhangsan:密码@127.0.0.1:27017/wzk_test1?authSource=wzk_test1'
// 允许:写入/查询
use wzk_test1db.collection('demo').insertOne({a:1})db.collection('demo').find({a:1})// 默认不能查看“其他数据库列表”
show dbs // 需要 listDatabases 权限
最小化授权
管理员分权
- 平台管理员:root(仅少量人员掌握)。
- DB 管理员:dbAdminAnyDatabase + userAdminAnyDatabase。
- 集群管理员:clusterAdmin(分片/复制集管理)。
应用分权
- 读写:readWrite@
- 只读:read@
- DDL/索引:dbOwner@ 或自定义角色(尽量别给 readWriteAnyDatabase)。
密码轮换
- 新建临时用户 → 应用切换凭据 → 删除旧用户(或更新 pwd 并同步配置管理/密钥库)。
审计要点
开启 auditLog(企业版)或至少保留 systemLog;对高危操作(增删角色、授予 root)保留变更记录。
错误速查
| 现象/报错 | 可能原因 | 核验命令 | 解决动作 |
|---|---|---|---|
| Authentication failed / SCRAM | 用户/密码错;authSource 错 | db.runCommand({connectionStatus:1,showPrivileges:true}) | 用 URI 指定 ?authSource=<db>;核对用户是否建在 wzk_test1/admin |
not authorized on <db> to execute | 角色权限不足 | db.getUser('<user>') | 补授所需动作(如 readWrite/dbOwner) |
| listDatabases 被拒 | 未授 listDatabases | db.adminCommand({listDatabases:1}) | 管理/只读账号按需授 readAnyDatabase(谨慎) |
| Failed to set up listener: key file permissions | KeyFile 权限不安全 | ls -l /path/keyfile | chown mongod:mongod keyfile && chmod 600 keyfile |
| 开启 authorization 后所有客户端都失败 | 先启用了授权但尚无 admin 用户 | - | 按“localhost 例外”在本机创建首个 admin(或临时停授权,见回滚) |
| user is not allowed to do action dropDatabase | 角色不含 DDL | db.getUser() | 使用 dbOwner 或授予对应 actions 的自定义角色 |
回滚剧本
仅用于救援,执行前隔离网络或绑定 127.0.0.1,避免暴露无授权实例。
单实例:
-
停服:mongod --shutdown --config mongodb.conf
-
临时以无授权方式、仅绑定本机启动:
mongod --port 27017 --bind_ip 127.0.0.1 --dbpath /data/db --fork
–logpath /data/db/mongodb-rollback.log --logappend -
连接本机,修复用户/角色:创建/重置 adminUser 密码或增授权限。
-
正常关闭后,按启用授权的配置重启。
分片集群:
- 优先通过 mongos 使用 clusterAdmin/root 账号修复;避免逐节点关授权。
- 如必须降级,先全员绑定 127.0.0.1,并在维护窗口逐步处理(顺序:configsvr→shard→mongos),修复后恢复授权。
其他系列
🚀 AI篇持续更新中(长期更新)
AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈
🔗 AI模块直达链接
💻 Java篇持续更新中(长期更新)
Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
🔗 Java模块直达链接
📊 大数据板块已完成多项干货更新(300篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
🔗 大数据模块直达链接
