外观
MongoDB 授权模型
内置角色体系
数据库用户角色
read:
- 允许读取指定数据库中的所有集合
- 包含权限:
find、aggregate、listCollections、listIndexes - 适用场景:只读用户
readWrite:
- 继承read角色的所有权限
- 增加写操作权限:
insert、update、remove、createIndex、dropIndex - 适用场景:读写用户
dbAdmin:
- 数据库管理权限
- 包含权限:
collMod、createCollection、dropCollection、renameCollection - 适用场景:数据库管理员
dbOwner:
- 数据库所有者权限
- 继承readWrite、dbAdmin和userAdmin角色
- 适用场景:数据库所有者
userAdmin:
- 用户管理权限
- 包含权限:
createUser、dropUser、updateUser、grantRolesToUser - 适用场景:用户管理员
集群管理角色
clusterAdmin:
- 集群管理最高权限
- 继承clusterManager、clusterMonitor和hostManager角色
- 包含权限:
addShard、removeShard、shutdown - 适用场景:集群管理员
clusterManager:
- 集群管理权限
- 包含权限:
replSetConfigure、replSetGetStatus、addShard - 适用场景:集群配置管理员
clusterMonitor:
- 集群监控权限
- 包含权限:
serverStatus、replSetGetStatus、getCmdLineOpts - 适用场景:监控用户
hostManager:
- 主机管理权限
- 包含权限:
setParameter、serverStatus、shutdown - 适用场景:主机管理员
备份恢复角色
backup:
- 备份权限
- 包含权限:
listDatabases、dbAdmin(所有数据库)、find(所有数据库) - 适用场景:备份用户
restore:
- 恢复权限
- 包含权限:
listDatabases、dbAdmin(所有数据库)、insert(所有数据库) - 适用场景:恢复用户
超级用户角色
root:
- 超级用户权限
- 继承所有内置角色
- 包含权限:
anyAction(所有资源) - 适用场景:超级管理员
__system:
- 内部系统角色
- MongoDB内部使用
- 不建议在生产环境使用
自定义角色创建
创建自定义角色
基本语法:
javascriptdb.createRole({ role: "角色名称", privileges: [ { resource: { 资源描述 }, actions: ["操作列表"] }, // 更多权限 ], roles: [ { role: "继承角色", db: "数据库" }, // 更多继承角色 ] })创建示例:
javascript// 创建一个只能读取特定集合的角色 db.createRole({ role: "readOrders", privileges: [ { resource: { db: "sales", collection: "orders" }, actions: ["find", "aggregate"] } ], roles: [] })创建带条件的角色:
javascript// 创建一个只能读取自己数据的角色 db.createRole({ role: "readOwnData", privileges: [ { resource: { db: "users", collection: "profiles" }, actions: ["find"], conditions: { field: "userId", operator: "$eq", value: "$$CURRENT_USER" } } ], roles: [] })
查看自定义角色
查看所有角色:
javascript// 查看当前数据库的所有角色 db.getRoles({ showPrivileges: true, showBuiltinRoles: true })查看特定角色:
javascript// 查看readOrders角色 db.getRole("readOrders", { showPrivileges: true })
修改和删除自定义角色
修改角色:
javascript// 修改readOrders角色,增加write权限 db.updateRole("readOrders", { privileges: [ { resource: { db: "sales", collection: "orders" }, actions: ["find", "aggregate", "insert", "update"] } ] })删除角色:
javascript// 删除readOrders角色 db.dropRole("readOrders")
权限资源与操作
资源类型
数据库资源:
javascript// 所有数据库 { anyResource: true } // 特定数据库 { db: "mydb", collection: "" }集合资源:
javascript// 特定集合 { db: "mydb", collection: "mycoll" } // 数据库中的所有集合 { db: "mydb", collection: "*" }集群资源:
javascript// 集群资源 { cluster: true }系统资源:
javascript// 系统.profile集合 { db: "local", collection: "system.profile" }
操作类型
读写操作:
find、insert、update、removeaggregate、count、distinct
管理操作:
createCollection、dropCollectioncreateIndex、dropIndexcollMod、renameCollection
集群操作:
replSetConfigure、replSetGetStatusaddShard、removeShardshutdown、setParameter
用户管理操作:
createUser、dropUser、updateUsergrantRolesToUser、revokeRolesFromUser
角色授予与撤销
授予角色给用户
创建用户时授予角色:
javascript// 创建用户并授予角色 db.createUser({ user: "john", pwd: "password123", roles: [ { role: "readWrite", db: "sales" }, { role: "read", db: "reporting" } ] })授予角色给现有用户:
javascript// 授予角色 db.grantRolesToUser("john", [ { role: "dbAdmin", db: "sales" }, "readOrders" // 自定义角色 ])
撤销用户角色
撤销角色:
javascript// 撤销角色 db.revokeRolesFromUser("john", [ { role: "dbAdmin", db: "sales" } ])替换用户角色:
javascript// 替换所有角色 db.updateUser("john", { roles: [ { role: "read", db: "sales" } ] })
权限继承关系
角色继承
垂直继承:
- 角色可以继承其他角色的权限
- 如readWrite继承read角色
水平继承:
- 角色可以继承多个不同角色
- 如dbOwner继承readWrite、dbAdmin和userAdmin
继承示例:
javascript// 创建一个继承多个角色的角色 db.createRole({ role: "salesManager", privileges: [], roles: [ { role: "readWrite", db: "sales" }, { role: "read", db: "reporting" }, "readOrders" // 自定义角色 ] })
权限继承规则
最小权限原则:
- 只授予必要的最小权限
- 避免过度授权
权限叠加原则:
- 继承的权限是叠加的
- 角色的权限是直接权限和继承权限的总和
权限覆盖原则:
- 明确的拒绝权限优先于允许权限
- 使用
denyActions指定拒绝的操作
权限审计与监控
启用审计日志
配置审计日志:
yaml# mongod.conf security: authorization: enabled auditLog: destination: file format: JSON path: /var/log/mongodb/audit.log filter: '{ "atype": "authCheck" }' # 只记录授权检查审计日志内容:
- 用户认证事件
- 权限检查事件
- 角色授予和撤销事件
监控权限使用
使用db.setProfilingLevel:
javascript// 启用慢查询和所有命令日志 db.setProfilingLevel(2, { slowms: 100 })查询审计日志:
javascript// 查看审计日志 db.adminCommand({ getLog: 'audit' })使用MongoDB Atlas:
- 内置权限使用监控
- 可视化权限使用报告
- 异常权限使用告警
最佳实践
最小权限原则
根据职责分配权限:
- 只读用户:read角色
- 读写用户:readWrite角色
- 管理员:根据需要分配特定角色
避免使用root角色:
- 生产环境中尽量不使用root角色
- 为不同管理员分配特定角色
定期审查权限:
javascript// 定期审查用户权限 db.getUsers({ showPrivileges: true, showCredentials: false })
角色命名规范
角色命名建议:
- 包含资源范围:如
sales_read、reporting_write - 包含职责:如
admin_cluster、backup_user - 使用下划线分隔:如
read_only_sales
- 包含资源范围:如
示例:
sales_read_write:sales数据库读写权限cluster_monitor:集群监控权限backup_restore:备份恢复权限
权限管理流程
权限申请:
- 用户提交权限申请
- 包含所需权限和理由
权限审批:
- 管理员审批权限申请
- 确保符合最小权限原则
权限授予:
- 授予相应角色
- 记录权限变更
权限审查:
- 定期审查权限使用情况
- 撤销不必要的权限
常见问题(FAQ)
Q1: 如何创建一个只能读取特定集合的角色?
A1: 可以使用db.createRole()创建自定义角色,指定资源为特定集合,操作为find和aggregate:
javascript
db.createRole({
role: "readSpecificCollection",
privileges: [
{
resource: { db: "mydb", collection: "mycoll" },
actions: ["find", "aggregate"]
}
],
roles: []
})Q2: 如何查看用户的所有权限?
A2: 使用db.getUser()命令查看用户权限:
javascript
db.getUser("username", { showPrivileges: true, showCredentials: false })Q3: 如何撤销用户的所有权限?
A3: 可以使用db.updateUser()替换用户的所有角色:
javascript
db.updateUser("username", {
roles: []
})Q4: 什么是最小权限原则?
A4: 最小权限原则是指只授予用户完成工作所需的最小权限,避免过度授权。这可以减少安全风险,防止误操作或恶意操作。
Q5: 如何监控权限使用情况?
A5: 可以通过以下方式监控权限使用:
- 启用审计日志,记录权限检查事件
- 使用数据库Profiler记录命令执行
- 使用第三方监控工具(如MongoDB Atlas)监控权限使用
Q6: 如何处理角色冲突?
A6: 角色冲突处理方法:
- 明确的拒绝权限优先于允许权限
- 避免授予相互冲突的角色
- 使用自定义角色精确控制权限
- 定期审查角色权限,确保没有冲突
