博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB账号管理及实践
阅读量:4946 次
发布时间:2019-06-11

本文共 4819 字,大约阅读时间需要 16 分钟。

此文已由作者温正湖授权网易云社区发布。

欢迎访问,了解更多网易技术产品运营经验。

目前蜂巢()MongoDB上已经有数十个实例,其中不少是企业用户或公司内部产品用户的。用户多了,那就会反馈一些问题。其中一个就是MongoDB实例访问账号,虽能够提供创建和删除集合、索引,创建数据库等用户所需的权限,但无法删除数据库,这个问题虽然不严重,但多少会影响用户体验。那么这是为什么呢?本文以此作为入口来谈谈MongoDB的账号管理。

MongoDB作为一个成熟的数据库,像MySQL一样,也提供账号管理,但又跟MySQL不大一样,MongoDB使用基于角色的访问权限控制(Role-Based Access Control,RBAC),包括账号(Users,直译为用户,但似乎账号更好理解)、角色(Roles)和权限(Privileges)三层关系。权限指的是允许对某种资源进行的某些操作。这里所说的资源,包括数据库、集合和集群等。在进行MongoDB权限管理操作时,资源使用一个文档来表示,比如数据库mydb下的集合mycoll作为一种资源表示为{db: "mydb", collection: "mycoll"}。{db: "mydb", collection: ""}表示数据库mydb下的所有集合。对应地,{db: "", collection: "mycoll"}就是所有数据库下的mycoll集合,集群资源表示为{cluster: true},如果要将所有数据库和集群作为一种资源那么可以表示为{anyResource: true}。所说的操作包括对集合的CRUD,查看数据库下的集合列表,查看复制集或分片集群当前状态等。根据操作类型,又可以分为:读写操作,数据库管理操作,集群部署操作,复制集操作,分片集群操作,系统管理操作,诊断操作,内部操作等8大类。

MongoDB对外提供的是账号,作为访问MongoDB认证单位。内部,一个账号可以由0到多个角色组成,角色分为内建角色(Built-In Roles)和自定义角色(User-Defined Roles)。为了方便使用,MongoDB提供了多种内建角色,分为数据库用户,数据库管理员,集群管理员,备份和恢复角色,跨数据库角色,超级用户,内部用户等7大类,每个大类下面有可以分为不同权限的角色,比如数据库用户大类可细分为读read和读写readWrite两种角色,而每个角色拥有一定的权限,比如角色具有创建/删除集合、创建删除索引和集合CRUD等16种权限,跨数据库角色表示该角色不仅对某个数据库有指定的操作权限,还对实例中其他所有(用户创建的)的数据库都具备同样的权限,比如readWriteAnyDatabase,具备对所有数据库有readWrite权限。这里有个特例,就是给用户授权角色时,如果授权时指定的数据库是admin,则即使仅指定readWrite,也同样具备readWriteAnyDatabase角色,也就是说对admin具有readWrite角色,那么对其他数据库也具有,天然具有AnyDatabase光辉。

蜂巢(云计算基础服务)MongoDB提供了MongoDB复制集实例,用户可以创建readWriteAnyDatabase权限的账号来访问MongoDB,为什么要AnyDatabase呢?因为我们还未提供MongoDB的数据库和账号管理功能(接管用户所有的数据库/集合、用户创建和权限管理操作),无法限制用户创建数据库,所以也就无法为特定某个数据库授予readWrite权限。readWriteAnyDatabase权限具备了复制集场景下用户所需的绝大部分权限,包括集合、索引的创建和删除,数据库/集合等统计信息。就像文章刚开始的描述一样,其不具备删除数据库(dropDatabase)这个权限,虽然有点坑,但还不是大问题,只需在后续提供MongoDB的数据库和账号管理功能中,将dropDatabase权限纳入管理即可。但在分片集群场景下,readWriteAnyDatabase所具有的的权限已经根本无法满足用户的正常操作,比如对数据库启用分片功能(enableSharding),人工进行分片的chunk拆分(splitChunk),在我们没有数据库和账号管理功能前,这些操作都需要用户端来执行,而readWriteAnyDatabase无法满足。那么是不是有其他内建角色满足需求呢,查阅官方文档发现集群管理员下的clusterManager角色提供了我们所需的权限,但其还提供了诸如在分片集群中添加和删除分片服务器,在复制集中进行复制集重配置等重型权限,如果给用户这些权限将是非常危险的。所以,在蜂巢分片集群实例中,无法通过为用户提供拥有多个内建角色(如readWriteAnyDatabase、clusterManager两个)的账号来满足用户正常使用的需求。这个时候,自定义角色就派送用场了,在创建自定义角色时,既可以指定对资源的操作权限,还可以选择继承另一个角色所拥有的权限,比如,提供给用户的新账号继承了readWriteAnyDatabase角色的所有权限,还额外添加了dropDatabase、enableSharding和splitChunk等权限,这样一来就顺利解决了面临的问题。

关说不练假把式,结合以上的描述,演示如何为MongoDB进行账号管理操作。

1、首先在mongod配置文件中增加权限相关设置 security: {authorization: enabled, keyFile: /home/mongo/keyfile}。其中authorization表示是否启用访问权限认证,keyFile指定了MongoDB复制集或分片集群内部各组件相互间通信的认证文件;MongoDB提供了本地例外机制,避免用户在启用认证前未设置账号导致无法访问MongoDB实例的尴尬;

2、创建用户所需的数据库账号,如下:

mongos> use admin

mongos> db.createUser(  {    user: "myuser",    pwd: "xxxxx",    roles: [ { role: "readWrite", db: "admin" } ]  } )

指定了认证数据库为admin,角色采用内建的readWrite,由于指定的数据库是admin,那么等同于创建了readWriteAnyDatabase角色的账号。用该账号登陆:

use admin

db.auth("myuser","wzh123")

3、但该账号无法执行如下这些操作:

mongos> use mydbmongos> db.dropDatabase(){	"ok" : 0,	"errmsg" : "not authorized on shardtest to execute command { dropDatabase: 1.0 }",	"code" : 13,	"codeName" : "Unauthorized"}mongos> sh.enableSharding("wzhshard"){	"ok" : 0,	"errmsg" : "not authorized on admin to execute command { enableSharding: \"wzhshard\" }",	"code" : 13,	"codeName" : "Unauthorized"}

4、所以,只能通过创建自定义角色来满足需求,先切换到root账号:

use admin

db.auth("root","wzh123") // root为已创建的具备超级用户角色的管理账号。

创建自定义角色: db.createRole({ role: "wzhRole", privileges: [{ resource: { db: "", collection: "" }, actions: ["enableSharding","dropDatabase" ] }], roles: ["readWriteAnyDatabase"] })

privileges字段指定了该角色具有的对resource字段所述资源具有actions字段所述的操作权限enableSharding和dropDatabase,同时通过roles字段继承了readWriteAnyDatabase的所有权限。

5、进一步操作myuser账号,先去掉其readWrite角色,操作如下:

db.revokeRolesFromUser(    "myuser",    [      { role: "readWrite", db: "admin" }    ])

确认权限已收回:

mongos> db.getUser("myuser"){	"_id" : "admin.myuser",	"user" : "myuser",	"db" : "admin",	"roles" : [ ]}

6、为myuser增加wzhRole角色:

db.grantRolesToUser(    "myuser",    [      { role: "wzhRole", db: "admin" }    ])

确认权限已经赋予:

db.getUser("myuser"){	"_id" : "admin.myuser",	"user" : "myuser",	"db" : "admin",	"roles" : [		{			"role" : "wzhRole",			"db" : "admin"		}	]}

7、再使用myuser登陆

use admin

db.auth("myuser","wzh123")

8、执行操作:

mongos> sh.enableSharding("wzhshard"){ "ok" : 1 }mongos> sh.shardCollection("wzhshard.table1",{mykey:1}){ "collectionsharded" : "wzhshard.table1", "ok" : 1 }mongos> use wzhshardswitched to db wzhshardmongos> db.dropDatabase(){ "dropped" : "wzhshard", "ok" : 1 }

一切看起来那么美好!

MongoDB在权限管理中引入了角色这一中间层,一般情况下,直接基于内建角色来创建账号即可,有特殊需求的话,可以创建自定义角色来满足需求,这样一来就无需暴露繁多的具体权限。对于新司机,更容易上手。但不足之处在于MongoDB数据库并未像MySQL一样未提供IP过滤功能(未提供Host字段用来设置账号所适用的主机IP列表)。

最后,网易数据库团队正在热火朝天地调研和开发MongoDB分片集群功能,计划上半年在蜂巢(云计算基础服务)上提供MongoDB分片集群能力,届时将带给大家更加强大的文档数据库能力。

网易云数据库是一种稳定可靠、可弹性伸缩的在线关系型数据库服务,当前支持MySQL引擎,提供基础版,高可用版,金融版针对不同业务场景的高可用解决方案,同时提供多重安全防护措施,性能监控体系,专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。

参考资料:

1、

2、

3、

4、

5、

6、

网易云,0成本体验20+款云产品! 

更多网易技术、产品、运营经验分享请。

相关文章:

【推荐】 
【推荐】 

转载于:https://www.cnblogs.com/zyfd/p/9814787.html

你可能感兴趣的文章
【SignalR学习系列】3. SignalR实时高刷新率程序
查看>>
物联网之RFID使用——小学生到校通报系统
查看>>
康德的道德观与哲学观
查看>>
“获取硬盘信息失败,请谨慎操作”的解决方案
查看>>
signed 与 unsigned 有符号和无符号数
查看>>
c++链栈
查看>>
c# winform 根据窗体自动调整控件
查看>>
MyBatis 查询
查看>>
一键GHOST优盘版安装XP/win7系统
查看>>
MyEclipse xml 手动添加 dtd
查看>>
字符串操作函数
查看>>
anyproxy-修改返回内容(beforeSendResponse)
查看>>
3基本概念
查看>>
iOS 触摸的位置放一个大头针
查看>>
Apache无法启动解决 the requested operation has failed
查看>>
【转】MYSQL 日期使用总结
查看>>
Spring.Net学习系列 - 第一篇HelloWorld
查看>>
总结macOS全新安装
查看>>
使用map集合添加菜单,运用反射,获取方法,执行程序
查看>>
JS学习笔记11_高级技巧
查看>>