分片集群用户必须通过mongos创建,元数据存于config server以统一授权;角色权限严格按库隔离,跨库需分步授权;root不覆盖业务库权限,需显式授予readWriteAnyDatabase等角色;节点间通信认证不可缺失。

分片集群中用户必须在 mongos 上创建,不能直连分片
直连某个 mongod 分片创建的用户,其角色只对该分片本地 admin 库生效,mongos 路由层完全不可见——这意味着应用连接 mongos 时认证失败,或认证通过但权限被静默忽略。
正确做法是始终通过 mongosh 连接 mongos 实例(如 mongosh --host my-mongos:27017 -u admin -p --authenticationDatabase admin),再执行用户操作。此时用户元数据写入 config server 的 admin.system.users,所有分片才能统一读取权限策略。
- 配置文件中确保
mongos启用了security.authorization: enabled - 连接
mongos后,先use admin,再调用db.createUser()或db.grantRolesToUser() - 不要在分片节点上运行
rs.initiate()后立刻创建用户——那只是临时本地用户,不参与集群 RBAC
角色作用域严格绑定数据库,跨库权限需显式声明
MongoDB 的角色没有隐式继承或全局作用域。readWrite 在 myapp 库和 analytics 库是两个独立权限集;root 角色只在 admin 数据库下有效,且仅对 admin 库内资源授权。
业务应用若需访问多个库,必须为同一用户分别在各目标库中授予权限:
- 先
use myapp,执行db.grantRolesToUser("appuser", ["readWrite"]) - 再
use analytics,执行db.grantRolesToUser("appuser", ["read"]) - 不能用
db.createUser({roles: [{role:"readWrite", db:"myapp"}, {role:"read", db:"analytics"}]})一次性创建——该语法仅支持单库上下文,多库角色必须分步授予
内置角色如 root / clusterAdmin 不自动覆盖分片数据权限
很多人误以为在 admin 库创建 root 用户后,就能无条件读写所有业务分片上的任意集合。实际上,root 只赋予对 admin、config 和 local 系统库的完全控制权,对业务库(如 orders)仍需显式授权。
真正能跨分片操作业务数据的角色是 readWriteAnyDatabase 和 dbAdminAnyDatabase,但它们也必须在 admin 库下授予,且仅当用户连接的是 mongos 时才生效:
db.runCommand({createUser:"ops", pwd:"xxx", roles:["readWriteAnyDatabase"], mechanisms:["SCRAM-SHA-256"]})- 该用户登录后,仍需指定目标库(如
use orders)才能执行db.orders.find() - 注意:
readWriteAnyDatabase不等于“绕过所有权限检查”,它仍受mongos的路由级权限校验约束
副本集内部通信认证缺失会导致分片集群启动失败
启用 RBAC 后,如果只配了客户端访问控制,却没配置节点间通信认证,mongos 无法与分片或 config server 建立可信连接,整个集群会卡在初始化阶段,日志里反复出现 Unable to reach primary 或 No primary found。
必须额外配置内部身份验证机制:
- 使用密钥文件:所有
mongod和mongos进程启动时加--keyFile /srv/mongodb/keyfile,且文件权限设为600 - 或改用 x.509:在配置文件中设置
security.clusterAuthMode: x509,并为每个节点签发对应证书 - 密钥文件或证书必须在所有组件间共享一致,否则节点拒绝加入集群
最容易被跳过的环节是 config server 的认证配置——它既是元数据存储,也是集群信任锚点,漏配会导致整个分片权限体系形同虚设。


















