新建角色需等待1–2分钟后台同步且必须显式绑定账号才生效,权限配置错误或未在admin库创建会导致授权失败。

新建角色后无法立即读取数据,不是权限没生效,而是角色配置变更需要后台同步,且账号必须显式绑定该角色才拥有对应权限。
角色创建后需等待约2分钟才真正可用
控制台或 shell 中执行 db.createRole() 后,MongoDB 内核会将角色定义写入 admin.system.roles,但权限校验服务不会实时加载。系统后台有异步刷新机制,通常需 1–2 分钟完成全节点同步(尤其在副本集或分片集群中)。此时即使角色已出现在 db.getRoles() 结果里,新账号用它连接仍可能报 not authorized on db to execute command。
- 不要依赖
db.getRoles({showPrivileges: true})返回即表示可用 - 验证方式:用新账号连接后执行
db.runCommand({connectionStatus: 1}),检查authInfo.roles是否包含刚建的角色 - 若 3 分钟后仍不生效,检查是否误在非
admin库创建了角色(自定义角色默认必须建在admin)
账号未绑定角色,新建角色等于白建
角色本身不自动赋予任何账号——它只是权限模板。你必须显式调用 db.grantRolesToUser() 或创建账号时通过 roles 字段指定,否则账号只有默认的空权限集。
- 常见错误:只运行了
db.createRole({role: "report_reader", ...}),却忘了db.grantRolesToUser("report_user", ["report_reader"]) - 如果用云数据库控制台创建账号,务必在“授权”步骤中勾选刚建的自定义角色,不能只点“确定”跳过
- 绑定后仍无效?检查
db.getUser("report_user")输出的roles数组是否真包含该角色名及对应数据库(如{role: "report_reader", db: "admin"})
权限范围写错,导致“能连上却读不了”
自定义角色的 privileges.resource 配置错误,是读取失败最隐蔽的原因。比如想让角色只能读 orders 库下的 main 表,但写成了 {db: "orders", collection: ""}(空字符串匹配所有集合)或 {db: "", collection: "main"}(空 db 不匹配任何库)。
- 必须严格按格式:读单个集合要写
{db: "orders", collection: "main"};读整个库用{db: "orders", collection: ""} - 内置角色如
read是库级,readAnyDatabase才能跨库;自定义角色无法绕过这个层级限制 - 测试时用
db.runCommand({listCollections: 1, filter: {name: "main"}})看是否返回结果,比直接find更早暴露权限问题
最容易被忽略的是:角色权限修改后,所有已绑定账号立即生效,但旧连接会复用缓存的权限上下文。重启应用连接或显式执行 db.logout() 再重连,才能确保拿到最新权限快照。











