MongoDB用户必须在admin库创建才能获得跨库权限,如readAnyDatabase;角色作用域由roles[].db指定,需与authenticationDatabase一致,且必须启用security.authorization才生效。

用户必须在 admin 库创建,但权限作用域可以跨库
MongoDB 的 db.createUser() 命令本身可以在任意数据库执行,但只有在 admin 库创建的用户,才能被授予跨库角色(如 readAnyDatabase)或集群级角色(如 clusterAdmin)。业务账号建议统一在 admin 库创建,避免后续扩展受限。
关键约束是:用户认证时指定的 --authenticationDatabase(或 db.auth({user:"u", db:"xxx"}) 中的 db 参数)必须与角色定义中 roles[].db 字段一致——不是用户所在库,而是角色“声明生效的库”。
- 错误做法:
use myapp→db.createUser({user:"app", roles:[{role:"readWrite", db:"admin"}]}),此时角色绑定在myapp库,db:"admin"不会被识别 - 正确做法:
use admin→db.createUser({user:"app", roles:[{role:"readWrite", db:"myapp"}]}),再用mongosh -u app -p --authenticationDatabase admin连接 - 验证方式:
db.runCommand({connectionStatus: 1})查看authInfo.roles是否含预期db值
内置角色够用就别自定义,尤其避免 root 和 readAnyDatabase
绝大多数业务场景用不到自定义角色。直接组合内置角色更安全、更易维护。比如一个订单服务账号,{role:"readWrite", db:"orders"} + {role:"read", db:"products"} 就比写个自定义角色包揽两个库更清晰。
root 和 readAnyDatabase 属于高危角色,仅限初始化管理员或 DBA 运维账号。应用服务账号一旦拿到它们,等于绕过所有库级隔离,审计和最小权限原则就失效了。
-
readWrite已包含insert/update/remove/find,无需额外加collMod等动作 - 需要索引管理?补一个
{role:"dbAdmin", db:"orders"}即可,不用重写 privilege - 想限制到集合级?内置角色做不到,这时才考虑
db.createRole(),且必须在admin库执行
集合级权限必须显式声明 resource.db 和 resource.collection
自定义角色若要限制到某张表(比如只允许查 orders.status 字段),不能只靠内置角色,必须用 db.createRole() 定义 privileges。这里最容易错的是字段拼写和空值处理。
resource.collection 是必填项;若想授权整个库(如建索引),得写 { db: "myapp", collection: "" } 或 { db: "myapp", collection: "*" }(后者仅 MongoDB 6.0+ 支持)。
- 错误:
{ resource: { db: "myapp" }, actions: ["find"] }→ 报错 “collection is required” - 错误:
{ resource: { db: "myapp", collection: "order" }, actions: ["find"] }→ 实际集合名是orders,权限不生效 - 正确:
{ resource: { db: "myapp", collection: "orders" }, actions: ["find"] }
分片集群必须在 mongos 创建用户,不能直连 shard
在分片集群中,用户元数据只存于 config server 的 admin 库,mongos 是唯一能统一解析角色并路由权限检查的入口。如果用 mongosh --host shard01:27018 直连某个分片创建用户,该用户角色只在那个分片本地生效,其他分片不可见,导致权限行为不一致——同一查询在不同节点返回 Unauthorized 或成功。
- 必须用
mongosh --host mongos-host:27017 -u admin -p --authenticationDatabase admin连接mongos - 创建用户前先
use admin,再执行db.createUser() - 验证:从任意应用端连接
mongos,运行db.runCommand({connectionStatus: 1}),确认authInfo.roles列表完整
最常被忽略的一点是:权限模型生效的前提是服务启动时已启用 security.authorization: enabled。光创建用户、赋角色,不重启 mongod 并开启访问控制,所有权限设置都形同虚设——连 not authorized 错误都不会报,而是直接拒绝连接或静默失败。











