MongoDB shell无内置角色继承树命令,需用JavaScript递归解析roles数组生成缩进视图;脚本需在admin库执行,注意role@db拼接、避免循环引用,并以usersInfo+getRole合并权限才能准确审计。

mongo shell 里没有内置角色继承树命令
直接执行 db.runCommand({ rolesInfo: 1 }) 或 db.getRoles({ showPrivileges: true }) 只返回扁平角色列表,不体现 roles 字段中声明的继承关系。MongoDB 官方 shell 不提供类似 tree 的递归展开功能,必须手动解析嵌套的 roles 数组。
用 JavaScript 脚本在 mongo shell 中递归打印继承路径
把以下脚本粘贴进 mongo shell(确保已连接到 admin 数据库)即可生成缩进式继承视图:
function printRoleTree(roleName, db, depth = 0) {
const indent = " ".repeat(depth);
print(indent + roleName);
const role = db.getRole(roleName, { showPrivileges: false, showBuiltinRoles: true });
if (!role || !Array.isArray(role.roles)) return;
role.roles.forEach(r => {
printRoleTree(r.role + "@" + (r.db || "admin"), db, depth + 1);
});
}
printRoleTree("root", db.getSiblingDB("admin"));
注意点:
-
role.role和role.db必须拼接,例如"readWrite@myapp",否则递归会查错数据库上下文 - 内置角色(如
root、readWriteAnyDatabase)需在admin库中查询,传错db实例会导致getRole返回 null - 脚本不处理循环引用,若人为配置了 A → B → A,会无限递归——生产环境应先用
db.runCommand({ rolesInfo: { role: "A", db: "admin" } })检查roles字段是否含闭环
用 mongosh 替代旧版 mongo 并启用 --eval 更适合自动化
新版 mongosh 支持模块化脚本和更好的错误提示。可将上述函数存为 role-tree.js,然后执行:
mongosh "mongodb://localhost:27017/admin" --eval "load('role-tree.js'); printRoleTree('backup', db, 0)"
关键差异:
-
mongosh默认启用 ESM,支持import,但此处用load()兼容性更好 - 连接字符串末尾的
/admin决定了默认数据库,影响db.getSiblingDB()行为 - 旧版
mongo已弃用,某些 6.0+ 特性(如按roleName@db精确匹配)在旧 shell 中可能返回空结果
真正要查清权限来源时,别只盯继承树
一个用户最终权限是「直接授予角色 + 所有继承角色」的并集,但冲突时以最细粒度为准。比如:
- 角色 A 授予
{ resource: { db: "foo", collection: "" }, actions: ["find"] } - 角色 B 授予
{ resource: { db: "foo", collection: "bar" }, actions: ["insert"] } - 用户同时拥有 A 和 B → 对
foo.bar有find + insert,但对foo.baz只有find
所以继承树只是起点;真要审计权限,得用 db.runCommand({ usersInfo: { user: "u", db: "admin" } }) 拿到完整角色列表,再逐个调 getRole 拆解,最后合并所有 privileges —— 这步没法靠一条命令跳过。


















