MongoDB原生不支持按集合粒度授权,最小权限单位是数据库;需在admin库用db.createRole()定义自定义角色,显式声明privileges资源(如{db:"appdb",collection:"users"})和actions,且版本须≥4.0、启用authorization并指定authSource=admin。

直接答案:MongoDB原生不支持「按集合粒度授权」
你无法用内置角色(如 readWrite)直接限制用户只访问某个集合——它最小作用域是数据库。想做到集合级控制,必须用自定义角色 + 显式声明资源,且仅限 MongoDB 4.0+(带 privileges 的角色定义方式)。
创建集合级权限角色必须用 db.createRole()
内置角色全部以数据库为单位,read、readWrite 等都对整个库生效。要锁定到集合,得自己定义角色:
- 角色必须在
admin数据库中创建(即使权限只针对其他库的集合) -
privileges字段里明确写出{ db: "mydb", collection: "users" }这类资源路径 - 每个动作(如
"find"、"insert")都要单独列在actions数组里 - 不能混用内置角色和自定义 privilege;一旦用了
privileges,就不再继承任何内置行为
示例(在 admin 库执行):
db.createRole({
role: "users_readonly",
privileges: [{
resource: { db: "appdb", collection: "users" },
actions: ["find"]
}],
roles: []
})
给用户分配集合角色时,db 参数必须匹配资源声明
创建用户时指定的角色 db 值,和你在 privileges.resource.db 里写的值无关——它只决定「这个角色定义存放在哪个库」。但实际生效依赖两点:
- 用户必须在
admin库创建(因为角色定义在admin) - 用户登录时连接的默认数据库(
--eval或连接串里的authSource)必须是admin,否则角色不加载 - 即使用户连的是
appdb,只要认证源是admin,且角色里声明了{ db: "appdb", collection: "users" },权限就生效
错误写法(角色存在但不生效):
use appdb
db.createUser({ user: "u1", pwd: "p1", roles: [{ role: "users_readonly", db: "appdb" }] }) // ❌ db 应该是 "admin"
正确写法:
use admin
db.createUser({ user: "u1", pwd: "p1", roles: [{ role: "users_readonly", db: "admin" }] }) // ✅
容易被忽略的兼容性与调试点
这套机制在副本集或分片集群上行为一致,但有三个硬性前提:
- MongoDB 版本 ≥ 4.0(3.6 及更早不支持
privileges字段) -
security.authorization必须设为enabled,且服务重启后生效 - 客户端连接必须显式指定
authSource=admin,例如:mongodb://u1:p1@localhost:27017/appdb?authSource=admin - 测试权限时别用
localhostexception(未建用户前本地可绕过认证),务必用远程 IP 或非 127.0.0.1 地址验证
权限不生效?先运行 db.runCommand({ connectionStatus: 1 }) 看 authInfo.roles 是否包含你分配的角色——没出现说明认证源或角色名写错了。


















