一、简介
之前写了下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.内部角色
角色类别 | 角色名 | 能执行的操作 | 解释 |
数据库用户角色 | read | changeStream,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, 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的角色之和 | ||
userAdmin | changeCustomData,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.角色相关命令
方法名 | 描述 |
---|---|
创建一个角色并制定其权限 | |
删除用户定义的角色 | |
删除用户定义的所有角色 | |
返回指定角色信息 | |
返回一个库的所有用户定义角色信息 | |
将权限分配给用户定义的角色 | |
从用户定义的角色中删除指定权限 | |
从用户指定的角色中继承权限 | |
从角色中删除继承的角色 | |
修改一个用户自定义角色 |
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个节点才向用客户端确认
- {w: 0} 对客户端的写入不需要发送任何确认,适用于性能要求高,但不关注正确性的场景
- {w: 1} 默认的writeConcern,数据写入到Primary就向客户端发送确认
- {w: “majority”} 数据写入到副本集大多数成员后向客户端发送确认,适用于对数据安全性要求比较高的场景,该选项会降低写入性能
2.2 j: 写入操作的journal持久化后才向客户端确认
- 默认为”{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是如何确认数据已成功写入到大多数节点的?
- Client向Primary发起请求,指定writeConcern为{w: “majority”},Primary收到请求,本地写入并记录写请求到oplog,然后等待大多数节点都同步了这条/批oplog(Secondary应用完oplog会向主报告最新进度)。
- Secondary拉取到Primary上新写入的oplog,本地重放并记录oplog。为了让Secondary能在第一时间内拉取到主上的oplog,find命令支持一个awaitData的选项,当find没有任何符合条件的文档时,并不立即返回,而是等待最多maxTimeMS(默认为2s)时间看是否有新的符合条件的数据,如果有就返回;所以当新写入oplog时,备立马能获取到新的oplog。
- Secondary上有单独的线程,当oplog的最新时间戳发生更新时,就会向Primary发送replSetUpdatePosition命令更新自己的oplog时间戳。
- 当Primary发现有足够多的节点oplog时间戳已经满足条件了,向客户端发送确认。