前面文章中通过客户端工具(MongoDB Shell、Robo 3T)连接 MongoDB 服务时,只要有 IP 地址和端口号,就能连接到数据库,之后就能操作数据库。这是因为默认安装的 MongoDB 没有启用身份验证,也没有设置初始用户名和密码。然而这会导致很多数据安全问题。
MongoDB 提供了多种方式来提高数据库的安全性,例如身份验证、访问控制、加密等。
本文主要介绍 MongoDB 提供的内置角色和权限,然后通过开启身份验证,为用户指定不同的访问权限,来提供数据库的安全性。
前两篇文章,我们分别在 Windows,Linux 和 Docker 中安装了 MongoDB 数据库。本文所介绍的内容,以 Linux 环境中的 MongoDB 为例进行演示。Windows 系统中的操作基本一致。
验证即身份验证。用户在连接到 MongoDB 服务时,需要提供用户名,密码和验证数据库进行身份的验证。
授权就是权限控制。做过后台管理系统的小伙伴肯定对 RBAC 模型不陌生。MongoDB 也采用了 RBAC 模型,创建用户时需要为其指定角色,来获取相应的操作数据库的权限。
身份验证只是限制用户能否连接数据库服务,而通过权限控制,就能更精细的控制用户对数据库的各种操作。类比常见的后台管理系统,管理员和普通用户都能登录系统,然后他们能访问的页面、能做的操作却大有不同。
MongoDB 通过 RBAC 授予用户对数据和命令的访问权限,并提供了多种内置角色来提供数据库系统中通常需要的不同级别的访问权限。除了使用内置角色,还支持用户创建定义的角色。
这一部分的内容官网有详尽的说明,我们先了解一些常用的角色和权限。
数据库读写角色:
数据库管理员角色:
所有数据库角色:
超级用户角色:
本文中我们主要用到 root
角色来设置数据库的超级管理员,然后使用 read
和 dbOwner
角色来为某个数据库创建不同权限的用户。
在启动 MongoDB 服务时,通过设置 --auth
在命令行中开启身份验证:
$ mongod -f /data/mongodb/mongodb.conf --auth
或者在配置文件开启 security.authorization
:
security:
authorization: enabled
如下,此时 MongoDB 服务已经开启了身份验证:
总结:
开启身份验证:
启动 mongod 服务时,使用 --auth;
使用 mongosh 客户端工具连接到 mongod 服务;
创建一个超级管理员账号;
MongoDB 开启身份验证后,是没有默认的用户名和密码的,需要自己进行设置。
使用 mongosh
连接服务:
$ mongosh
开启验证后,即使不输入用户名密码也能进入到数据库中,但此时没有权限操作数据库,比如:
此时唯一能做的事情就是创建一个超级管理员角色的用户。
创建超级管理员需要进入 admin
数据库,然后使用 db.createUser
方法创建用户:
use admin;
db.createUser({
user: "Kunwu",
pwd: "abc123",
roles: [
{ role: "root", db: "admin"}
]
});
配置项说明:
root
。root
角色的特殊性,这里只能设置为 admin
。但是具备了 root
角色的用户,具有超级权限。开启身份验证后,通过客户端工具(MongoDB Shell、Robo 3T 等)连接到 MongoDB 服务时,需要指定用户名和密码,有两种验证方式。
在连接数据库服务时指定用户名和认证数据库:
$ mongosh -u Kunwu --authenticationDatabase admin
-u/–user:指定用户名
–authenticationDatabase:指定认证数据库。认证数据库,就是创建用户时所处的那个数据库。上文创建 Kunwu 时所在的数据库是 admin,所以他的认证数据库就是 admin。
然后命令行中会提示你输入密码:
输入密码后,回车确认即可登录:
也可以直接在命令行通过 -p/--password
来输入密码:
$ mongosh -u Kunwu -p abc123 --authenticationDatabase admin
先不提供用户名、密码和验证数据库,而是在连接到数据库服务之后,进入认证数据库,使用 db.auth 方法验证用户名和密码。
$ mongosh
验证身份:
use admin;
db.auth('Kunwu', 'abc123');
创建一个新连接。在 Connection
中输入数据库服务的 IP 和端口:
在第二个 Authentication
中依次输入:
然后点击左下角的测试按钮,进行连接测试:
之后就可以使用 Robo 3T 来管理数据库库了。
认证数据库,就是指创建用户时所处于的那个数据库。比如前文是在 admin
数据库中创建的超级管理员的用户 Kunwu
,那么此用户的验证数据库就是 admin
。在登录数据库时,authenticationDatabase
就需要指定为 admin
。
验证数据库并不意味着用户只能操作这一个数据库。
MongoDB 中内置了多种角色,创建用户时可以指定多个角色和数据库,此时指定的数据库才是用户能操作的数据库。比如:
db.createUser({
user: "Kunwu",
pwd: "abc123",
roles: [
{ role: "read", db: "db1"},
{ role: "readWrite", db: "db2"},
{ role: "dbOwner", db: "db2"},
]
});
此时,用户 Kunwu
就能操作 db1、db2、db3 这三个数据库,并且具备不同的权限。
所以,结论就是认证数据库并不等同于用户能操作的数据库,这是两个不同的概念。
超级用户具备最高权限,它适合用来管理其他用户,而不应该用来操作具体的数据库。
我们需要为每一个应用创建单独的用户,来使用数据库服务。比如有一个管理系统 manage
,可以为它创建多个用户,有的只能读取数据,有的可以读写数据,有的具备完全权限等等。
先以超级管理员身份登录到MongoDB中:
$ mongosh -u Kunwu -p abc123 --authenticationDatabase admin
然后为 manage
数据库创建不同的用户:
use manage;
db.create({
user: 'ManageAdmin',
pwd: 'admin123',
roles: [
{ role: "dbOwner", db: 'manage'}
]
});
db.create({
user: 'ManageRead',
pwd: 'user123',
roles: [
{ role: "read", db: 'manage'}
]
})
dbOwner
角色的用户拥有对 manage 数据库执行任何操作的能力。而 read
角色的用户只能从数据库中读取数据。
使用 manage 数据库的管理员用户登录:
$ mongosh -u ManageAdmin -p admin123 --authenticationDatabase manage
使用 manage 数据库的普通用户登录:
$ mongosh -u ManageRead -p user123 --authenticationDatabase manage
到这里,我们简单介绍了 MongoDB 的身份验证和授权的机制。
对于新安装的 MongoDB ,它是没有开启身份验证的。需要进入 admin
数据库,创建一个 root
角色的超级管理员用户。之后再针对具体应用的数据库,使用管理员用户为其创建不同权限的用户,从而做到针对数据库安全的基本保障。
关于角色权限还有很多内容,比如某个角色具体拥有哪些权限,如何创建自定义角色,如何修改用户密码,更新角色等等,大家可以自行访问官网或者查阅其他资料。
感谢阅读!