必须在admin数据库中执行db.createUser()并显式声明{role,db}对,否则跨库权限不生效;因MongoDB仅在admin库解析roles中db字段,非admin库执行时会静默忽略db值,导致权限绑定到当前库而非目标库。

必须在 admin 数据库中执行 db.createUser(),并为每个目标数据库显式声明 {role, db} 对,否则跨库权限不会生效。
为什么非 admin 库里创建的用户无法跨库授权
MongoDB 解析 roles 数组中的 db 字段,仅在 admin 库执行时才真正持久化;在其他库(如 test)执行时,db: "prod" 这类字段会被静默忽略,实际只存 {role: "readWrite", db: "test"}。
常见错误现象:
- 用户连上后对目标库执行
db.collection.find()报错:not authorized on prod to execute command - 用
db.getUser("appuser")查看角色,发现roles里所有db值都是当前创建库名,而非预期库名
如何正确创建跨库用户(admin 库 + 显式 roles)
先切换到 admin,再调用 db.createUser(),roles 中每个对象都必须同时包含 role 和 db 字段:
use admin
db.createUser({
user: "appuser",
pwd: "strongpass123",
roles: [
{ role: "readWrite", db: "orders" },
{ role: "read", db: "users" },
{ role: "dbAdmin", db: "logs" }
]
})
关键点:
-
use admin是强制前置步骤,不是可选 -
role名必须准确(大小写敏感),例如"readWrite"有效,"readwrite"无效 -
db字段值必须是已存在或未来会创建的数据库名,不能拼错 - 角色名只能是内置角色(如
"readWrite"、"dbOwner")或已在对应db中预定义的自定义角色
连接时必须指定 --authenticationDatabase admin
即使用户被授予了多个库的权限,登录时认证库仍必须明确指向 admin,否则 MongoDB 默认在当前库(比如你 mongo orders)尝试认证,导致 Authentication failed。
正确连接方式示例:
mongo -u appuser -p strongpass123 --authenticationDatabase admin
后续 use orders 或 use users 都无需再次 db.auth(),权限自动生效。
容易忽略的点:
- 应用连接字符串中遗漏
authSource=admin(等价于--authenticationDatabase admin) - 误以为只要用户在
admin库创建,就能在任意库用db.auth()登录——其实db.auth()只对当前库生效,且不继承跨库角色 - 混淆
readWriteAnyDatabase和手动列{role, db}:前者权限过大、违反最小权限原则,且不适用于需要精细控制的生产环境
最易出错的环节是:没切到 admin 就执行 createUser,或者连接时忘了传 --authenticationDatabase admin。这两个动作缺一不可,且顺序不能颠倒。











