mongo-用户及角色管理

一、简介

之前写了下mongo的部署,mongo部署可以说是比较简单的,因为我的配置文件里写了免密认证,所以我们登录是不需要验证的,但是为了安全,还是要做验证比较好

二、用户

1.用户管理命令

方法名描述
db.getUsers()获取用户信息
db.dropAllUsers()删除所有用户
db.updateUser()修改用户信息
db.createUser()创建用户
db.revokeRolesFromUser()删除用户角色
db.removeUser()删除用户(已经废弃)
db.grantRolesToUser()授予用户角色
db.getUser()查看指定用户信息
db.changeUserPassword()修改用户密码
db.auth()数据库认证、安全模式
db.dropUser() 删除用户

1.1 简介

MongoDB默认情况下不启用访问控制。您可以使用--auth或 security.authorization设置启用授权。启用内部身份验证也会启用客户端授权。

启用访问控制后,用户必须进行身份验证

1.2 相关命令演示

use admin
# 1.创建用户
db.createUser(
  {
    user: "myUserAdmin",
    pwd: passwordPrompt(), // 这里也可以直接写密码
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)
# 这时候会让你输入密码,输入你想给admin用户设置的密码即可
db.createUser(
  {
    user: "myUserAdmin",
    pwd: '123', // 这里也可以直接写密码
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)


# 2.查看用户信息(该语句会列出所有用户信息)
db.getUsers();|show users;(两个语句都行)
[
	{
		"_id" : "admin.admin",
		"userId" : UUID("8c02adf8-14a8-4b66-8a1f-780dc1e929b5"),
     。。。

# 3.查看指定用户信息
db.getUser('admin')
{
	"_id" : "admin.admin",
	"userId" : UUID("8c02adf8-14a8-4b66-8a1f-780dc1e929b5"),
     。。。

# 4.删除指定用户
db.dropUser('admin')


# 5.删除所有用户
db.dropAllUsers()

# 6.修改用户密码
db.changeUserPassword('admin','456')

# 7.非用户登录mongo后再进行认证
 db.auth('admin','456')

# 8.更改用户信息
db.updateUser(
   "admin",
   {
     mechanisms: [ "SCRAM-SHA-256" ]
   }
)

# 9.给用户授权
db.grantRolesToUser(
   "admin",
   [ "readWrite" , { role: "read", db: "stock" } ],
   { w: "majority" , wtimeout: 4000 }
)

# 10.回收用户权限
db.revokeRolesFromUser( "admin",
                        [ { role: "read", db: "stock" }, "readWrite" ],
                        { w: "majority" }
                      )

三、角色

1.内部角色

角色类别角色名能执行的操作解释
数据库用户角色readchangeStream,collStats,dbHash,dbStats,find,killCursors,listIndexes,listCollections允许用户读取指定数据库

readWrite

collStats,convertToCapped,createCollection,dbHash,dbStats,dropCollection,createIndex,dropIndex,
find,insert,killCursors,listIndexes,listCollections,remove,renameCollectionSameDB,update
允许用户读写指定数据库
数据库管理角色dbAdmin

系统权限:changeStream,collStats,convertToCapped,createCollection,dbHash,dbStats,dropCollection,find,
killCursors,listIndexes,listCollections,planCacheRead
数据库权限:

bypassDocumentValidation,collMod,collStats,convertToCapped,createCollection,createIndex,dbStats,dropCollection,

dropDatabase,dropIndex,enableProfiler,listIndexes,listCollections,planCacheIndexFilter,planCacheRead,planCacheWrite,

reIndex,renameCollectionSameDB,storageDetails,validate

允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
dbOwner实际是readWrite, dbAdmin和userAdmin的角色之和
userAdminchangeCustomData,changePassword,createRole,createUser,dropRole,dropUser,grantRole,revokeRole,
setAuthenticationRestriction,viewRole,viewUser
允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
集群管理角色clusterAdmin

整个集群上:

addShard,appendOplogNote,applicationMessage,cleanupOrphaned,flushRouterConfig,listSessions (版本3.6中的新功能),listShards,removeShard,replSetConfigure,replSetGetConfig,replSetGetStatus,replSetStateChange,resync

,setFeatureCompatibilityVersion,setFreeMonitoring

所有数据库:

clearJumboFlag (4.2.3和4.0.15中的新功能),enableSharding,moveChunk,splitChunk,splitVector

config库的非系统集合:

collStats,dbHash,dbStats,enableSharding,find,insert,killCursors,listCollections,listIndexes,moveChunk,planCacheRead,remove,

splitChunk,splitVector,update

config库的系统集合:

collStats,dbHash,dbStats,find,killCursors,listCollections,listIndexes,planCacheRead

local库的非系统集合:

enableSharding,insert,moveChunk,remove,splitChunk,splitVector,update

local库的系统集合:

collStats,dbHash,dbStats,find,killCursors,listCollections,listIndexes,planCacheRead

只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
clusterManager

整个集群上:

checkFreeMonitoringStatus (版本4.0中的新增功能),connPoolStats,getCmdLineOpts,getLog,getParameter,getShardMap,hostInfo,inprog,listDatabases,listSessions (版本3.6中的新功能),listShards,netstat,replSetGetConfig,replSetGetStatus,serverStatus,setFreeMonitoring (版本4.0中的新增功能),shardingState,top

所有数据库:

collStats,dbStats,getShardVersion,indexStats,useUUID (版本3.6中的新功能)

config库的非系统集合:

collStats,dbHash,dbStats,find,getShardVersion,indexStats,killCursors,listCollections,listIndexes,planCacheRead

config库的系统集合:

collStats,dbHash,dbStats,find,killCursors,listCollections,listIndexes,planCacheRead

clusterMoniter
hostManager
备份恢复角色backup
store
所有数据库角色readAnyDatabase只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
超级用户角色root只在admin数据库中可用。超级账号,超级权限
内部角色__system

2.角色相关命令

方法名

描述

db.createRole()

创建一个角色并制定其权限

db.dropRole()

删除用户定义的角色

db.dropAllRoles()

删除用户定义的所有角色

db.getRole()

返回指定角色信息

db.getRoles()

返回一个库的所有用户定义角色信息

db.grantPrivilegesToRole()

将权限分配给用户定义的角色

db.revokePrivilegesFromRole()

从用户定义的角色中删除指定权限

db.grantRolesToRole()

从用户指定的角色中继承权限

db.revokeRolesFromRole()

从角色中删除继承的角色

db.updateRole()

修改一个用户自定义角色

2.1 角色相关命令演示

use admin
# 1.创建角色
db.createRole(
   {
     role: "myClusterwideAdmin",
     privileges: [
       { resource: { cluster: true }, actions: [ "addShard" ] },
       { resource: { db: "config", collection: "" }, actions: [ "find", "update", "insert", "remove" ] },
       { resource: { db: "users", collection: "usersCollection" }, actions: [ "update", "insert", "remove" ] },
       { resource: { db: "", collection: "" }, actions: [ "find" ] }
     ],
     roles: [
       { role: "read", db: "admin" }
     ]
   },
   { w: "majority" , wtimeout: 4000 }
)

# 利用上面的特性可以做到把权限粒度控制在集合上,注意这里下面的roles不要给任何权限,只通过peivileges来控制,然后把col_ro的角色赋给对应的用户即可
# privileges中的actions操作可以通过官网查看:https://www.mongodb.com/docs/v4.4/reference/privilege-actions/#std-label-security-user-actions
db.createRole(
   {
     role: "col_ro", 
     privileges: [
       { resource: { db: "db_name", collection: "col_name" }, actions: [ "find" ] }
     ],
     roles: []
   }
)

db.createUser(
  {
    user: "app_col_ro",
    pwd: 'password',
    roles: [ { role: "col_ro", db: "db_name"} ]
  }
)

# 2.查看单库角色
db.getRoles()
# 因为我们是在admin创建的库,所以都可以看到,可以试试如下演示
use config
db.createRole(
   {
     role: "test_config",
     privileges: [
       { resource: { db: "config", collection: "" }, actions: [ "find", "update", "insert", "remove" ] }
     ],
     roles: [
       { role: "read", db: "config" }
     ]
   },
   { w: "majority" , wtimeout: 4000 }
)
use admin
db.getRoles()



# 3.查看指定角色信息
db.getRole('test')

# 4.查看所有角色,包括内置角色
show roles

# 5.删除指定自建角色
db.dropRole('test')

# 6.删除所有自建角色
db.dropAllRoles()

# 7.将权限分配给用户定义的角色
db.grantPrivilegesToRole(
  "test_config",
  [
    {
      resource: { db: "config", collection: "test" },
      actions: [ "find" ]
    }
  ],
  { w: "majority" }
)

# 8.从用户定义的角色中删除指定权限
db.revokePrivilegesFromRole(
  "test_config",
  [
    {
      resource: { db: "config", collection: "test" },
      actions: [ "find" ]
    }
  ],
  { w: "majority" }
)

# 9.从用户指定的角色中继承权限
db.grantRolesToRole(
    "test_config",
    [ "readWrite" ],
    { w: "majority" , wtimeout: 5000 }
)

# 10.从角色中删除继承的角色
db.revokeRolesFromRole(
    "test_config",
    [ "readWrite" ],
    { w: "majority" , wtimeout: 5000 }
)

# 11.修改一个用户自定义角色
db.updateRole(
    "test_config",
    {
      privileges:
          [
            {
              resource: { db:"config", collection:"test1" },
              actions: [ "update", "createCollection", "createIndex"]
            }
          ],
      roles:
          [
            {
              role: "readWrite",
              db: "config"
            }
          ]
    },
    { w:"majority" }
)

四、writeConcern文档

1.格式

{ w: <value>, j: <boolean>, wtimeout: <number> }

2.选项详解

2.1 w: 数据写入到number个节点才向用客户端确认

  1. {w: 0} 对客户端的写入不需要发送任何确认,适用于性能要求高,但不关注正确性的场景
  2. {w: 1} 默认的writeConcern,数据写入到Primary就向客户端发送确认
  3. {w: “majority”} 数据写入到副本集大多数成员后向客户端发送确认,适用于对数据安全性要求比较高的场景,该选项会降低写入性能

2.2 j: 写入操作的journal持久化后才向客户端确认

  1. 默认为”{j: false},如果要求Primary写入持久化了才向客户端确认,则指定该选项为true

2.3 wtimeout: 写入超时时间,仅w的值大于1时有效。

当指定{w: }时,数据需要成功写入number个节点才算成功,如果写入过程中有节点故障,可能导致这个条件一直不能满足,从而一直不能向客户端发送确认结果,针对这种情况,客户端可设置wtimeout选项来指定超时时间,当写入过程持续超过该时间仍未结束,则认为写入失败。

3.{w: “majority”}解析

{w: 1}、{j: true}等writeConcern选项很好理解,Primary等待条件满足发送确认;但{w: “majority”}则相对复杂些,需要确认数据成功写入到大多数节点才算成功,而MongoDB的复制是通过Secondary不断拉取oplog并重放来实现的,并不是Primary主动将写入同步给Secondary,那么Primary是如何确认数据已成功写入到大多数节点的?

  1. Client向Primary发起请求,指定writeConcern为{w: “majority”},Primary收到请求,本地写入并记录写请求到oplog,然后等待大多数节点都同步了这条/批oplog(Secondary应用完oplog会向主报告最新进度)。
  2. Secondary拉取到Primary上新写入的oplog,本地重放并记录oplog。为了让Secondary能在第一时间内拉取到主上的oplog,find命令支持一个awaitData的选项,当find没有任何符合条件的文档时,并不立即返回,而是等待最多maxTimeMS(默认为2s)时间看是否有新的符合条件的数据,如果有就返回;所以当新写入oplog时,备立马能获取到新的oplog。
  3. Secondary上有单独的线程,当oplog的最新时间戳发生更新时,就会向Primary发送replSetUpdatePosition命令更新自己的oplog时间戳。
  4. 当Primary发现有足够多的节点oplog时间戳已经满足条件了,向客户端发送确认。

官网地址:Role Management Methods — MongoDB Manual

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值