角色与权限管理(内置角色、自定义角色)
角色与权限管理的基本概念
MongoDB的权限系统基于角色(Role)和权限(Privilege)构建。角色是一组权限的集合,可以分配给用户。权限定义了在特定资源上允许的操作。MongoDB提供了内置角色,也支持创建自定义角色来满足特定需求。
权限由资源和操作组成。资源可以是数据库、集合、集群或特定文档;操作包括find、insert、update、delete等CRUD操作,以及管理操作如createCollection、dropDatabase等。
内置角色类型
MongoDB内置角色分为以下几类:
-
数据库用户角色:
- read:允许读取指定数据库的非系统集合
- readWrite:提供read角色的所有权限,加上写入权限
-
数据库管理角色:
- dbAdmin:允许执行管理操作,如索引创建、统计收集
- userAdmin:允许在当前数据库创建和修改用户与角色
- dbOwner:组合了readWrite、dbAdmin和userAdmin角色
-
集群管理角色:
- clusterAdmin:提供最大的集群管理访问权限
- clusterManager:提供监控和管理集群的权限
- clusterMonitor:提供只读访问监控工具
- hostManager:允许监控和管理服务器
-
备份恢复角色:
- backup:提供备份数据所需的权限
- restore:提供从备份恢复数据所需的权限
-
全数据库角色:
- readAnyDatabase:提供所有数据库的只读权限
- readWriteAnyDatabase:提供所有数据库的读写权限
- userAdminAnyDatabase:提供所有数据库的userAdmin权限
- dbAdminAnyDatabase:提供所有数据库的dbAdmin权限
-
超级用户角色:
- root:提供所有资源的完全访问权限
自定义角色创建
当内置角色不能满足需求时,可以创建自定义角色。创建角色需要指定:
- 角色名称
- 角色所在的数据库
- 权限(privileges)
- 继承的角色(roles)
// 创建自定义角色示例
use admin
db.createRole({
role: "appAdmin",
privileges: [
{
resource: { db: "appDB", collection: "" },
actions: ["find", "insert", "update", "remove", "createIndex"]
},
{
resource: { db: "appDB", collection: "logs" },
actions: ["find"]
}
],
roles: [
{ role: "read", db: "config" }
]
})
角色管理操作
常用角色管理命令包括:
- 查看所有角色:
db.getRoles({ showBuiltinRoles: true })
- 查看特定角色:
db.getRole("appAdmin", { showPrivileges: true })
- 更新角色:
db.updateRole("appAdmin", {
privileges: [
{
resource: { db: "appDB", collection: "" },
actions: ["find", "insert", "update", "remove", "createIndex", "dropIndex"]
}
],
roles: [
{ role: "read", db: "config" },
{ role: "read", db: "local" }
]
})
- 删除角色:
db.dropRole("appAdmin")
用户与角色分配
创建用户时可以分配角色:
use admin
db.createUser({
user: "appUser",
pwd: "securePassword123",
roles: [
{ role: "appAdmin", db: "admin" },
{ role: "readWrite", db: "appData" }
]
})
也可以后续为用户添加或移除角色:
// 添加角色
db.grantRolesToUser("appUser", [
{ role: "dbAdmin", db: "appDB" }
])
// 移除角色
db.revokeRolesFromUser("appUser", [
{ role: "readWrite", db: "appData" }
])
权限继承与组合
角色可以继承其他角色的权限,形成层次结构:
// 创建基础角色
db.createRole({
role: "baseRole",
privileges: [
{
resource: { db: "appDB", collection: "users" },
actions: ["find", "insert"]
}
],
roles: []
})
// 创建扩展角色
db.createRole({
role: "extendedRole",
privileges: [
{
resource: { db: "appDB", collection: "users" },
actions: ["update", "remove"]
}
],
roles: [
{ role: "baseRole", db: "admin" }
]
})
最佳实践
- 最小权限原则:只授予完成工作所需的最小权限
- 角色分层:创建基础角色和扩展角色,避免重复定义权限
- 定期审计:定期检查用户和角色分配情况
- 环境隔离:为开发、测试和生产环境使用不同的角色和权限
- 文档记录:维护角色和权限的文档说明
实际应用场景示例
电商平台权限设计:
// 产品管理角色
db.createRole({
role: "productManager",
privileges: [
{
resource: { db: "ecommerce", collection: "products" },
actions: ["find", "insert", "update"]
},
{
resource: { db: "ecommerce", collection: "categories" },
actions: ["find", "insert", "update"]
}
],
roles: []
})
// 订单处理角色
db.createRole({
role: "orderProcessor",
privileges: [
{
resource: { db: "ecommerce", collection: "orders" },
actions: ["find", "update"]
},
{
resource: { db: "ecommerce", collection: "customers" },
actions: ["find"]
}
],
roles: []
})
// 管理员角色(继承多个角色)
db.createRole({
role: "ecommerceAdmin",
privileges: [
{
resource: { db: "ecommerce", collection: "" },
actions: ["createCollection", "dropCollection"]
}
],
roles: [
{ role: "productManager", db: "admin" },
{ role: "orderProcessor", db: "admin" },
{ role: "dbAdmin", db: "ecommerce" }
]
})
权限验证与测试
验证用户权限的方法:
// 模拟用户操作
db.auth("appUser", "securePassword123")
// 检查权限
db.runCommand({
rolesInfo: { role: "appAdmin", db: "admin" },
showPrivileges: true
})
// 测试特定操作是否允许
try {
db.getSiblingDB("appDB").products.insertOne({ name: "Test" })
print("Insert operation allowed")
} catch (e) {
print("Insert operation denied: " + e.message)
}
跨数据库权限管理
管理多个数据库的权限:
// 创建跨数据库角色
db.createRole({
role: "multiDBAnalyst",
privileges: [
{
resource: { db: "sales", collection: "" },
actions: ["find"]
},
{
resource: { db: "inventory", collection: "" },
actions: ["find"]
},
{
resource: { db: "reports", collection: "monthly" },
actions: ["find", "insert", "update"]
}
],
roles: []
})
// 分配给用户
db.updateUser("analystUser", {
roles: [
{ role: "multiDBAnalyst", db: "admin" },
{ role: "read", db: "shared" }
]
})
权限与集合级别控制
精细控制到集合级别:
// 财务数据特殊权限
db.createRole({
role: "financialAccess",
privileges: [
{
resource: { db: "corporate", collection: "transactions" },
actions: ["find", "insert"]
},
{
resource: { db: "corporate", collection: "salaries" },
actions: ["find"]
},
{
resource: { db: "corporate", collection: "auditLogs" },
actions: ["find", "insert", "update"]
}
],
roles: []
})
// 受限财务角色
db.createRole({
role: "financialReadOnly",
privileges: [
{
resource: { db: "corporate", collection: "transactions" },
actions: ["find"]
},
{
resource: { db: "corporate", collection: "auditLogs" },
actions: ["find"]
}
],
roles: []
})
系统集合权限管理
系统集合需要特殊权限:
// 允许访问system.profile集合
db.createRole({
role: "profileAccess",
privileges: [
{
resource: { db: "", collection: "system.profile" },
actions: ["find"]
}
],
roles: []
})
// 允许修改system.users集合
db.createRole({
role: "userManagement",
privileges: [
{
resource: { db: "admin", collection: "system.users" },
actions: ["find", "insert", "update", "remove"]
},
{
resource: { db: "admin", collection: "system.roles" },
actions: ["find", "insert", "update", "remove"]
}
],
roles: []
})
权限与应用程序集成
在Node.js应用中集成MongoDB权限:
const { MongoClient } = require('mongodb');
async function connectWithRoles() {
const client = new MongoClient('mongodb://appUser:securePassword123@localhost:27017/admin');
try {
await client.connect();
const db = client.db('appDB');
// 执行有权限限制的操作
const result = await db.collection('products').insertOne({
name: 'New Product',
price: 99.99
});
console.log('Insert result:', result);
// 尝试无权限的操作
try {
await db.dropCollection('products');
} catch (err) {
console.log('Expected error (no drop permission):', err.message);
}
} finally {
await client.close();
}
}
connectWithRoles().catch(console.error);
权限管理的常见问题
- 权限缓存:MongoDB会缓存权限信息,修改权限后可能需要重新认证
- 权限冲突:多个角色的权限可能产生冲突,拒绝优先于允许
- 资源模式:可以使用正则表达式匹配多个集合
db.createRole({ role: "logAccess", privileges: [ { resource: { db: "appDB", collection: /^logs_/ }, actions: ["find", "insert"] } ], roles: [] })
- 认证数据库:用户创建在哪个数据库很重要,影响认证过程
- 副本集和分片:在集群环境中,权限管理需要在所有节点上一致
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:用户管理与访问控制