mongodb集合级权限必须通过自定义角色实现,不能依赖内置角色;需在createrole中显式声明每个db+collection组合,大小写敏感且不支持通配符,权限作用域与当前use数据库无关。

createUser 时必须指定 resource.db 和 resource.collection
集合级权限不能靠内置角色(如 readWrite)实现,必须用用户自定义角色 + 显式资源限定。直接给用户分配 readWrite 角色,权限粒度是整个数据库,不是集合。
正确做法是先创建角色,再把角色赋予用户。角色定义里每个 privilege 都要带 { db: "mydb", collection: "orders" } 这样的完整资源路径:
db.createRole({
role: "orders_reader",
privileges: [{
resource: { db: "mydb", collection: "orders" },
actions: ["find"]
}],
roles: []
})
-
resource.db必须和实际数据库名完全一致,大小写敏感 -
collection字段不能为空字符串或通配符("*"不被支持) - 一个角色可包含多个
privilege,分别控制不同集合,但不能跨库混写(比如一个 privilege 里db: "a"、另一个里db: "b",必须分角色或分用户)
连接时默认库不等于权限作用域
用户登录后,即使连接串指定了 /mydb,也不代表自动获得该库下所有集合权限——RBAC 只认角色里明确定义的 resource,跟当前 use mydb 无关。
常见错误:用户在 mydb 库执行 db.orders.find() 报错 not authorized on mydb to execute command find,其实是因为角色没声明 { db: "mydb", collection: "orders" },只写了 { db: "mydb", collection: "" } 或干脆漏了 collection 字段。
- 验证方式:登录后运行
db.runCommand({ connectionStatus: 1 }).authInfo.roles,检查返回的角色是否含目标集合的精确匹配项 - 不要依赖
show collections判断权限——它只显示有listCollections权限的集合,而该权限通常由dbAdmin角色提供,和集合读写无关
GridFS 桶名必须隔离,且权限落到具体集合
GridFS 默认用 fs 作为 bucket 名,对应 fs.files 和 fs.chunks 两个集合。如果多租户共用同一个 bucket,仅靠 metadata.tenant_id 过滤,一旦查询漏条件或直连 shell,就可能越权读取其他租户文件。
必须为每个租户创建独立 bucket,并授予对应集合权限:
db.createRole({
role: "acme_files_rw",
privileges: [
{ resource: { db: "acme_001", collection: "tenant_acme_001.files" }, actions: ["find", "insert", "update", "remove"] },
{ resource: { db: "acme_001", collection: "tenant_acme_001.chunks" }, actions: ["find", "insert", "update", "remove"] }
],
roles: []
})
-
bucketName要动态生成(如tenant_acme_001),不能硬编码成fs - 权限必须明确落到
tenant_acme_001.files和tenant_acme_001.chunks,不能只授acme_001数据库级readWrite - 应用层调用
GridFSBucket时,bucketName参数必须与权限中声明的集合前缀严格一致
分片集群中集合级权限容易失效的点
在分片集群里,mongos 不会自动校验租户上下文,所有发往 mongos 的请求都按原始语句路由到 shard,RBAC 仅在各 shard 节点本地生效。如果 shard 上没提前建好对应角色,或者 authSource 指向错误,就会出现“认证通过但操作被拒”。
- 必须确保每个 shard 节点(而非仅
mongos)都已加载相同的角色定义——角色存在 config server,但权限检查发生在 shard 本地 - 客户端连接
mongos时,authSource必须显式设为admin,否则角色查不到(因为用户数据存于 config server 的admin.system.users) - 对集合执行
shardCollection前,务必确认该集合的权限已在所有相关 shard 上就位;否则分片后首次写入可能因权限缺失静默失败
collection 字段、混淆 authSource 与操作库、或在分片环境下忽略 shard 本地角色同步,都会让权限形同虚设。











