MongoDB的CURD基本操作(五)——用户、角色管理

注:本文基于MongoDB 4.2.6编写

1、用户管理

1、创建用户

> db.createUser( { user: "testuser", pwd: "test", roles:[]})
Successfully added user: { "user" : "testuser", "roles" : [ ] }

其中user指定用户名,pwd指定密码,roles指定该用户的角色,这个和权限相关,我们后面再讲。

如果不想明文指定密码,可通过passwordPrompt()使用键盘输入方式设置密码,

> db.createUser( { user: "me", pwd: passwordPrompt(), roles:[]})
Enter password: 
Successfully added user: { "user" : "me", "roles" : [ ] }

2、 查询用户

A、查询特定用户

> db.getUser("me")
{
	"_id" : "test.me",
	"userId" : UUID("b4a02c61-6d95-41f6-9d3b-11a5493a7476"),
	"user" : "me",
	"db" : "test",
	"roles" : [ ],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}
> 

B、查询当前数据库中的用户,有两种方式

> db.getUsers()
[
	{
		"_id" : "test.hello",
		"userId" : UUID("da14e1ba-dad7-4c2b-b15e-a59efffe49cc"),
		"user" : "hello",
		"db" : "test",
		"roles" : [ ],
		...
	},
	{
		"_id" : "test.me",
		"userId" : UUID("b4a02c61-6d95-41f6-9d3b-11a5493a7476"),
		"user" : "me",
		"db" : "test",
		"roles" : [ ],
		...
	}
]
> show users
{
	"_id" : "test.hello",
	"userId" : UUID("da14e1ba-dad7-4c2b-b15e-a59efffe49cc"),
	"user" : "hello",
	"db" : "test",
	"roles" : [ ],
	...
}
{
	"_id" : "test.me",
	"userId" : UUID("b4a02c61-6d95-41f6-9d3b-11a5493a7476"),
	"user" : "me",
	"db" : "test",
	"roles" : [ ],
	...
}

C、查询所有数据库中的用户

> use admin
switched to db admin
> db.system.users.find().pretty()
{
	"_id" : "abc.testuser",
	"userId" : UUID("64a2e8ad-a1e1-4733-8845-05f88fc49449"),
	"user" : "testuser",
	"db" : "abc",
	"credentials" : {
		...
	},
	"roles" : [ ]
}
{
	"_id" : "test.hello",
	"userId" : UUID("da14e1ba-dad7-4c2b-b15e-a59efffe49cc"),
	"user" : "hello",
	"db" : "test",
	"credentials" : {
		...
	},
	"roles" : [ ]
}
{
	"_id" : "test.me",
	"userId" : UUID("b4a02c61-6d95-41f6-9d3b-11a5493a7476"),
	"user" : "me",
	"db" : "test",
	"credentials" : {
		...
	},
	"roles" : [ ]
}

3、 修改用户密码

可以明文指定密码,也可以使用键盘输入方式,

> db.changeUserPassword("hello", "world")
> db.changeUserPassword("hello", passwordPrompt())
Enter password: 
>

4、 删除用户

删除特定用户

> db.dropUser("hello")
true

删除当前数据库所有用户

> db.dropAllUsers()
NumberLong(2)

2、角色管理

MongoDB通过RABC来对数据库资源和操作进行权限管理,简单来说就是将数据库权限,如读写删除等,以及资源,如表,集合等按照一定规则聚合成某一些组合,然后将这个组合关联到某个角色,比如普通管理员,admin管理员等,最后将用户与角色关联,从而完成权限管理和认证。K8S中也是采用这种方式来进行认证和授权管理。

默认情况下,MongoDB没有开启鉴权,因此我们只要输入mongo命令就能连接到本地的数据库,而且具有admin权限,

[root@localhost ~]# mongo --quiet
> show dbs
abc     0.000GB
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

而对于开放了公网权限的数据库(mongod监听所有地址),只要知道对方ip地址和服务端口,任何人都可以连接到这个数据库,并拥有root权限。因此如果你的数据未开启鉴权认证,又暴露在公网中,就很容易被一些人通过ip端口扫描的方式控制数据库。

1、开启鉴权

需要修改MongoDB配置文件/etc/mongod.conf,增加以下配置,

security:
  authorization: enabled

然后重启服务即可,

systemctl restart mongod

这时候再执行mongo命令连接数据库之后,基本上就无法执行操作,

[root@localhost ~]# mongod --quiet
> show dbs
> show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
>

此时就需要通过用户名和密码来访问连接数据库。但是由于我们上面讲的创建用户都没有关联角色,因此创建的用户能连接到数据库,但是很多权限都没有,因此我们需要创建带有角色的用户。

在创建这个带有角色的用户前,我们先了解一下有哪些角色,这些角色有哪些权限。

2、用户角色

1、数据库用户角色
  • read:非系统数据库读权限,比如查看集合
  • readWrite:非系统数据库读写权限,比如插入、更新、删除文档
2、数据库管理员角色
  • dbAdmin:拥有管理员权限,但是无用户管理和角色管理权限
  • userAdmin:拥有当前数据库的用户管理和角色管理权限,可以授予自己超管权限
  • dbOwner:拥有readWrite, dbAdmin和userAdmin角色的权限总和
3、集群管理员角色
  • clusterManager:用于集群管理和监控,能访问config和local数据库,用于分片和副本
  • clusterMonitor:拥有对监控工具的读取权限
  • hostManager:拥有监控和管理服务器权限
  • clusterAdmin:拥有clusterManager, clusterMonitor和hostManager角色的权限总和,并能执行dropDatabase操作

这些角色只能在Admin数据库下创建

4、备份和恢复角色
  • backup:拥有备份数据库权限
  • restore:拥有还原备份数据库权限

这些角色只能在Admin数据库下创建

5、所有数据库角色
  • readAnyDatabase:拥有对所有数据库的可读权限,除了config和local数据库
  • readWriteAnyDatabase:拥有对所有数据库的读写权限,除了config和local数据库
  • userAdminAnyDatabase:对所有数据库拥有userAdmin权限,除了config和local数据库,不过它可以授予自己任何权限,包括超管
  • dbAdminAnyDatabase:对所有数据库拥有dbAdmin权限,除了config和local数据库

这些角色只能在Admin数据库下创建

6、超级用户角色
  • root:超管,拥有所有权限,包括config和local数据库

这些角色只能在Admin数据库下创建

3、创建带角色的用户

介绍完各个角色之后,我们尝试创建我们需要的用户。

我们尝试创建一个超管用户,一个管理员用户,以及一个普通用户。

  • 超管
    记得要在开启认证前创建该用户,不然开启认证后就没权限了。
> use admin
switched to db admin
> db.createUser({user: "root", pwd: "root", roles: ["root"]})
Successfully added user: { "user" : "root", "roles" : [ "root" ] }
> db.getUser("root")
{
	"_id" : "admin.root",
	"userId" : UUID("333f11a3-74a1-4e5d-926e-9d4264098d03"),
	"user" : "root",
	"db" : "admin",
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	],
	...
}

而且,只能在admin数据库下创建超管用户,否则会报错,

> use test
switched to db test
> db.createUser({user: "root", pwd: "root", roles: ["root"]})
2020-06-17T10:07:55.883-0400 E  QUERY    [js] uncaught exception: Error: couldn't add user: No role named root@test :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.createUser@src/mongo/shell/db.js:1370:11
@(shell):1:1
> 
  • 管理员
    创建完超管后退出连接,开启连接认证,然后通过刚才的超管用户重新连接数据库,
[root@localhost ~]# mongo -u root -p  --quiet
Enter password: 
> use admin
switched to db admin
> db.createUser({user: "admin", pwd: "admin", roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"]})
Successfully added user: {
	"user" : "admin",
	"roles" : [
		"userAdminAnyDatabase",
		"readWriteAnyDatabase"
	]
}
> db.getUser("admin")
{
	"_id" : "admin.admin",
	"userId" : UUID("e62da4de-bb44-4bc8-b57e-3bd810d7bd4c"),
	"user" : "admin",
	"db" : "admin",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		},
		{
			"role" : "readWriteAnyDatabase",
			"db" : "admin"
		}
	],
	...
}
  • 普通用户
> use abc
switched to db abc
> db.createUser({user: "read", pwd: "read", roles: ["read"]})
Successfully added user: { "user" : "read", "roles" : [ "read" ] }
> 

用这个普通用户创建用户,或者读取其他数据库数据都会失败,

[root@localhost ~]# mongo -u read -p --host localhost:27017 --quiet --authenticationDatabase abc
Enter password: 
> use abc
switched to db abc
> db.createUser({user: "write", pwd: "write", roles: ["write"]})
2020-06-18T09:23:01.370-0400 E  QUERY    [js] uncaught exception: Error: couldn't add user: not authorized on abc to execute command { createUser: "write", pwd: "xxx", roles: [ "write" ], digestPassword: true, writeConcern: { w: "majority", wtimeout: 600000.0 }, lsid: { id: UUID("ce601eec-d1dd-489b-be3d-7364accf1423") }, $db: "abc" } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.createUser@src/mongo/shell/db.js:1370:11
@(shell):1:1
> use test
switched to db test
> show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
> use abc
switched to db abc
> show collections
bb

4、授予用户角色

> db.createUser({user: "hello", pwd: "hello", roles: []})
Successfully added user: { "user" : "hello", "roles" : [ ] }
> db.getUser("hello")
{
	"_id" : "admin.hello",
	"userId" : UUID("d8fb4612-4b05-4571-9746-9f4b7d62f27d"),
	"user" : "hello",
	"db" : "admin",
	"roles" : [ ],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}
> db.grantRolesToUser("hello", ["read", {role: "readWrite", db: "abc"}])
> db.getUser("hello")
{
	"_id" : "admin.hello",
	"userId" : UUID("d8fb4612-4b05-4571-9746-9f4b7d62f27d"),
	"user" : "hello",
	"db" : "admin",
	"roles" : [
		{
			"role" : "read",
			"db" : "admin"
		},
		{
			"role" : "readWrite",
			"db" : "abc"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

我们开始时创建了一个没有任何角色的用户,然后授予admin数据库的read角色,以及abc数据库的读写角色。

5、回收用户角色

角色能授予,自然也能收回,

> db.getUser("hello")
{
	"_id" : "admin.hello",
	"userId" : UUID("d8fb4612-4b05-4571-9746-9f4b7d62f27d"),
	"user" : "hello",
	"db" : "admin",
	"roles" : [
		{
			"role" : "read",
			"db" : "admin"
		},
		{
			"role" : "readWrite",
			"db" : "abc"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}
> db.revokeRolesFromUser("hello", [{role: "readWrite", db: "abc"}])
> db.getUser("hello")
{
	"_id" : "admin.hello",
	"userId" : UUID("d8fb4612-4b05-4571-9746-9f4b7d62f27d"),
	"user" : "hello",
	"db" : "admin",
	"roles" : [
		{
			"role" : "read",
			"db" : "admin"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

这里我们收回了hello用户对admin数据库的read角色。

6、创建角色

很多时候我们需要的权限比较复杂,系统自带的角色无法满足我们的要求,这是我们就可以自己动手,创建定制角色。

> db.createRole({role: "myAdmin", privileges: [{resource: {db: "test", collection: "aa"}, actions: ["find", "update"]}], roles: [{role: "read", db: "admin"},{role: "readWrite", db: "abc"}]})
{
	"role" : "myAdmin",
	...
}
> db.getRole("myAdmin")
{
	"role" : "myAdmin",
	"db" : "admin",
	"isBuiltin" : false,
	"roles" : [
		{
			"role" : "read",
			"db" : "admin"
		},
		{
			"role" : "readWrite",
			"db" : "abc"
		}
	],
	"inheritedRoles" : [
		{
			"role" : "read",
			"db" : "admin"
		},
		{
			"role" : "readWrite",
			"db" : "abc"
		}
	]
}

这里我们创建了一个角色myAdmin,拥有对test数据库aa集合的find和update操作,同时还拥有admin数据库的read角色,以及abc数据库readWrite角色。因此通过自己创建角色,可以实现多元化的权限需求和更精细的权限控制。

7、删除角色

可以创建角色,当然也可以删除角色,不过只能删除用户创建的角色,无法删除系统自带的角色,

> use admin
switched to db admin
> db.dropRole("myTest")
true
> db.dropRole("read")
2020-06-20T23:12:43.872-0400 E  QUERY    [js] uncaught exception: Error: read@admin is a built-in role and cannot be modified. :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.dropRole@src/mongo/shell/db.js:1681:11
@(shell):1:1
>

更多角色管理操作可以阅读MongoDB文档:https://docs.mongodb.com/manual/reference/method/js-role-management/


参考资料:
1、https://docs.mongodb.com/manual/reference/built-in-roles/#built-in-roles

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值