Skip to content

MongoDB 授权模型 ​

内置角色体系 ​

数据库用户角色 ​

  1. read:

    • 允许读取指定数据库中的所有集合
    • 包含权限:find、aggregate、listCollections、listIndexes
    • 适用场景:只读用户
  2. readWrite:

    • 继承read角色的所有权限
    • 增加写操作权限:insert、update、remove、createIndex、dropIndex
    • 适用场景:读写用户
  3. dbAdmin:

    • 数据库管理权限
    • 包含权限:collMod、createCollection、dropCollection、renameCollection
    • 适用场景:数据库管理员
  4. dbOwner:

    • 数据库所有者权限
    • 继承readWrite、dbAdmin和userAdmin角色
    • 适用场景:数据库所有者
  5. userAdmin:

    • 用户管理权限
    • 包含权限:createUser、dropUser、updateUser、grantRolesToUser
    • 适用场景:用户管理员

集群管理角色 ​

  1. clusterAdmin:

    • 集群管理最高权限
    • 继承clusterManager、clusterMonitor和hostManager角色
    • 包含权限:addShard、removeShard、shutdown
    • 适用场景:集群管理员
  2. clusterManager:

    • 集群管理权限
    • 包含权限:replSetConfigure、replSetGetStatus、addShard
    • 适用场景:集群配置管理员
  3. clusterMonitor:

    • 集群监控权限
    • 包含权限:serverStatus、replSetGetStatus、getCmdLineOpts
    • 适用场景:监控用户
  4. hostManager:

    • 主机管理权限
    • 包含权限:setParameter、serverStatus、shutdown
    • 适用场景:主机管理员

备份恢复角色 ​

  1. backup:

    • 备份权限
    • 包含权限:listDatabases、dbAdmin(所有数据库)、find(所有数据库)
    • 适用场景:备份用户
  2. restore:

    • 恢复权限
    • 包含权限:listDatabases、dbAdmin(所有数据库)、insert(所有数据库)
    • 适用场景:恢复用户

超级用户角色 ​

  1. root:

    • 超级用户权限
    • 继承所有内置角色
    • 包含权限:anyAction(所有资源)
    • 适用场景:超级管理员
  2. __system:

    • 内部系统角色
    • MongoDB内部使用
    • 不建议在生产环境使用

自定义角色创建 ​

创建自定义角色 ​

  1. 基本语法:

    javascript
    db.createRole({
      role: "角色名称",
      privileges: [
        { resource: { 资源描述 }, actions: ["操作列表"] },
        // 更多权限
      ],
      roles: [
        { role: "继承角色", db: "数据库" },
        // 更多继承角色
      ]
    })
  2. 创建示例:

    javascript
    // 创建一个只能读取特定集合的角色
    db.createRole({
      role: "readOrders",
      privileges: [
        { 
          resource: { db: "sales", collection: "orders" },
          actions: ["find", "aggregate"] 
        }
      ],
      roles: []
    })
  3. 创建带条件的角色:

    javascript
    // 创建一个只能读取自己数据的角色
    db.createRole({
      role: "readOwnData",
      privileges: [
        { 
          resource: { db: "users", collection: "profiles" },
          actions: ["find"],
          conditions: {
            field: "userId",
            operator: "$eq",
            value: "$$CURRENT_USER"
          }
        }
      ],
      roles: []
    })

查看自定义角色 ​

  1. 查看所有角色:

    javascript
    // 查看当前数据库的所有角色
    db.getRoles({ showPrivileges: true, showBuiltinRoles: true })
  2. 查看特定角色:

    javascript
    // 查看readOrders角色
    db.getRole("readOrders", { showPrivileges: true })

修改和删除自定义角色 ​

  1. 修改角色:

    javascript
    // 修改readOrders角色,增加write权限
    db.updateRole("readOrders", {
      privileges: [
        { 
          resource: { db: "sales", collection: "orders" },
          actions: ["find", "aggregate", "insert", "update"] 
        }
      ]
    })
  2. 删除角色:

    javascript
    // 删除readOrders角色
    db.dropRole("readOrders")

权限资源与操作 ​

资源类型 ​

  1. 数据库资源:

    javascript
    // 所有数据库
    { anyResource: true }
    
    // 特定数据库
    { db: "mydb", collection: "" }
  2. 集合资源:

    javascript
    // 特定集合
    { db: "mydb", collection: "mycoll" }
    
    // 数据库中的所有集合
    { db: "mydb", collection: "*" }
  3. 集群资源:

    javascript
    // 集群资源
    { cluster: true }
  4. 系统资源:

    javascript
    // 系统.profile集合
    { db: "local", collection: "system.profile" }

操作类型 ​

  1. 读写操作:

    • find、insert、update、remove
    • aggregate、count、distinct
  2. 管理操作:

    • createCollection、dropCollection
    • createIndex、dropIndex
    • collMod、renameCollection
  3. 集群操作:

    • replSetConfigure、replSetGetStatus
    • addShard、removeShard
    • shutdown、setParameter
  4. 用户管理操作:

    • createUser、dropUser、updateUser
    • grantRolesToUser、revokeRolesFromUser

角色授予与撤销 ​

授予角色给用户 ​

  1. 创建用户时授予角色:

    javascript
    // 创建用户并授予角色
    db.createUser({
      user: "john",
      pwd: "password123",
      roles: [
        { role: "readWrite", db: "sales" },
        { role: "read", db: "reporting" }
      ]
    })
  2. 授予角色给现有用户:

    javascript
    // 授予角色
    db.grantRolesToUser("john", [
      { role: "dbAdmin", db: "sales" },
      "readOrders" // 自定义角色
    ])

撤销用户角色 ​

  1. 撤销角色:

    javascript
    // 撤销角色
    db.revokeRolesFromUser("john", [
      { role: "dbAdmin", db: "sales" }
    ])
  2. 替换用户角色:

    javascript
    // 替换所有角色
    db.updateUser("john", {
      roles: [
        { role: "read", db: "sales" }
      ]
    })

权限继承关系 ​

角色继承 ​

  1. 垂直继承:

    • 角色可以继承其他角色的权限
    • 如readWrite继承read角色
  2. 水平继承:

    • 角色可以继承多个不同角色
    • 如dbOwner继承readWrite、dbAdmin和userAdmin
  3. 继承示例:

    javascript
    // 创建一个继承多个角色的角色
    db.createRole({
      role: "salesManager",
      privileges: [],
      roles: [
        { role: "readWrite", db: "sales" },
        { role: "read", db: "reporting" },
        "readOrders" // 自定义角色
      ]
    })

权限继承规则 ​

  1. 最小权限原则:

    • 只授予必要的最小权限
    • 避免过度授权
  2. 权限叠加原则:

    • 继承的权限是叠加的
    • 角色的权限是直接权限和继承权限的总和
  3. 权限覆盖原则:

    • 明确的拒绝权限优先于允许权限
    • 使用denyActions指定拒绝的操作

权限审计与监控 ​

启用审计日志 ​

  1. 配置审计日志:

    yaml
    # mongod.conf
    security:
      authorization: enabled
      auditLog:
        destination: file
        format: JSON
        path: /var/log/mongodb/audit.log
        filter: '{ "atype": "authCheck" }'  # 只记录授权检查
  2. 审计日志内容:

    • 用户认证事件
    • 权限检查事件
    • 角色授予和撤销事件

监控权限使用 ​

  1. 使用db.setProfilingLevel:

    javascript
    // 启用慢查询和所有命令日志
    db.setProfilingLevel(2, { slowms: 100 })
  2. 查询审计日志:

    javascript
    // 查看审计日志
    db.adminCommand({ getLog: 'audit' })
  3. 使用MongoDB Atlas:

    • 内置权限使用监控
    • 可视化权限使用报告
    • 异常权限使用告警

最佳实践 ​

最小权限原则 ​

  1. 根据职责分配权限:

    • 只读用户:read角色
    • 读写用户:readWrite角色
    • 管理员:根据需要分配特定角色
  2. 避免使用root角色:

    • 生产环境中尽量不使用root角色
    • 为不同管理员分配特定角色
  3. 定期审查权限:

    javascript
    // 定期审查用户权限
    db.getUsers({ showPrivileges: true, showCredentials: false })

角色命名规范 ​

  1. 角色命名建议:

    • 包含资源范围:如sales_read、reporting_write
    • 包含职责:如admin_cluster、backup_user
    • 使用下划线分隔:如read_only_sales
  2. 示例:

    • sales_read_write:sales数据库读写权限
    • cluster_monitor:集群监控权限
    • backup_restore:备份恢复权限

权限管理流程 ​

  1. 权限申请:

    • 用户提交权限申请
    • 包含所需权限和理由
  2. 权限审批:

    • 管理员审批权限申请
    • 确保符合最小权限原则
  3. 权限授予:

    • 授予相应角色
    • 记录权限变更
  4. 权限审查:

    • 定期审查权限使用情况
    • 撤销不必要的权限

常见问题(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: 角色冲突处理方法:

  • 明确的拒绝权限优先于允许权限
  • 避免授予相互冲突的角色
  • 使用自定义角色精确控制权限
  • 定期审查角色权限,确保没有冲突