usersInfo 返回的 roles 字段不全,因为它只显示用户在指定数据库中显式授予的角色,不展开内置角色权限、不显示跨库或集群级角色(如 userAdminAnyDatabase)、不递归解析角色继承链,且集群级权限必须在 admin 库中查询。

直接执行 db.runCommand({ usersInfo: { user: "用户名", db: "数据库名" } }) 即可查到该用户在指定数据库的全部权限,但注意:它不返回角色继承链的完整展开,也不显示集群级权限(如 root)在其他数据库中的实际生效范围。
为什么 usersInfo 返回的 roles 字段看起来“不全”
这个命令只列出用户在当前数据库(即 db 参数指定的库)中显式授予的角色,不会自动展开角色所包含的内置角色(如 readWrite)或跨库角色(如 userAdminAnyDatabase)。例如:
- 用户
appuser在myapp库被赋予readWrite角色 →usersInfo会返回{ role: "readWrite", db: "myapp" } - 但
readWrite实际包含哪些具体动作(如find、insert、update)?usersInfo不展开,得查官方文档或用show roles配合db.getSiblingDB("admin").runCommand({ rolesInfo: { role: "readWrite", db: "admin" } }) - 如果该用户还拥有
dbAdminAnyDatabase(在admin库授予),而你查的是myapp库,那这个角色根本不会出现在返回结果里
查集群级权限必须切换到 admin 数据库执行
MongoDB 的系统级角色(如 userAdminAnyDatabase、clusterAdmin)只能在 admin 库中定义和查询。若你在 test 库执行 usersInfo,即使用户有全局权限,你也看不到。
- 正确做法:
use admin db.runCommand({ usersInfo: { user: "admin_user", db: "admin" } }) - 错误做法:
use test后直接查,会漏掉所有非test库授予的角色 - 注意:
db字段在命令中仍需写成"admin",不能省略或写成当前库名
如何确认一个用户是否真能执行某操作(比如 dropDatabase)
usersInfo 只告诉你“有哪些角色”,不等于“能做什么”。MongoDB 权限是叠加+继承的,且受认证机制(SCRAM vs x.509)、连接方式(localhost exception)、网络策略共同影响。
- 最可靠验证方式:用该用户连接后,手动试一下关键操作,捕获错误信息 —— 比如
db.runCommand({ dropDatabase: 1 }),失败时返回的errmsg通常明确指出缺失哪类权限(如"not authorized on admin to execute command dropDatabase") - 别依赖
roles数组长度判断权限强弱:一个__system角色可能比五个自定义角色权限还大 - 审计时建议配合
db.authSchemaVersion和db.serverStatus().auth确认认证机制是否启用,否则usersInfo查到的用户可能根本未生效
真正麻烦的是权限继承路径过深(比如角色 A → B → C → 内置角色),usersInfo 不递归展开,你得一层层手动查 rolesInfo;另外,副本集或分片集群中,各节点的 admin 库用户元数据必须一致,否则同一用户在不同 mongos 上查出的权限可能不同。











