MongoDB学习笔记(六)——MongoDB配置用户账号与访问控制

前面的几篇博文,大概介绍了如何安装MongoDB,以及介绍了MongoDB shell与MongoDB Compass。

新安装的MongoDB是没有账号设置的,也就是说任何人都可以连接进MongoDB,这是非常不安全的。所以我们需要对MongoDB进行设置账号,来控制对数据库的访问。

admin数据库

admin数据库是MongoDB安装时就会自动创建的,如下图,是我用MongoDB Compass 连接本地新安装的MongoDB:
这里写图片描述
大家可以从上面看到,新安装的MongoDB默认创建三个数据库,admin、config、local.
- config数据库暂时不知道用处,如果谁知道,忘告知。
- local数据库内部有一个startup_log的集合,内部存储了连接MongoDB的记录信息。

对于admin数据库,这是一个比较特殊的数据库,具有一些普通数据库没有的功能,比如有些用户账号被赋予能够操作对个数据库的权限,这些角色就只能在admin中创建,比如能够操作所有数据库的超级用户,当然普通数据库也可以创建用户,但是普通数据库创建的用户只能用于创建用户的数据库。当连接验证用户的时候,MongoDB会从指定数据库的用户与admin的用户检查用户信息。

管理用户账号

管理用户账号,也就是添加、删除、配置用户记录。我们可以通过MongoDB shell 和 MongoDB Compass来操作,当然为了锻炼对MongoDB shell的熟悉,建议大家使用MongoDB shell。

  1. 创建用户账号

在创建用户前,我们使用createUser(user,writeConcern),该方法以前是addUser(),但是已经不能用了,使用createUser()代替。
(注:本博文的createUser适合版本较高,可能低版本的一些字段都无效了,这里就不在写了)
其中user的文档定义如下:

{
  user: "<name>",
  pwd: "<cleartext password>",
  customData: { <any information> },
  roles: [
    { role: "<role>", db: "<database>" } | "<role>",
    ...
  ],
  authenticationRestrictions: [
     {
       clientSource: ["<IP>" | "<CIDR range>", ...]
       serverAddress: ["<IP>" | "<CIDR range>", ...]
     },
     ...
  ]
}

writeConcern:该文档是该操作的关注等级(更多可以查看官方解释)
- w选项:允许的值分别是 1、0、大于1的值、”majority”、;
- j选项:确保mongod实例写数据到磁盘上的journal(日志),这可以确保mongd以外关闭不会丢失数据。设置true启用。
- wtimeout:指定一个时间限制,以毫秒为单位。wtimeout只适用于w值大于1。

                创建用户所需字段

字段 格式 描述
user 字符串 独一无二的用户名
roles 数组 一个用户的角色数组,MongoDB提供了大量可以分配的角色,详细可见下方的表格
pwd 字符串 可选,账号密码,该字段可以是散列值或字符串,不过存储是按照散列值的方式存储的
customData 任何数据 可选的。可以为任意信息。此字段可用于存储管理员希望与此特定用户关联的任何数据。例如,这可能是用户的全名或雇员id
authenticationRestrictions array 可选的。该字段为3.6版本以后的新特性,服务器在创建用户上强制执行的身份验证限制。指定可连接服务器的访问用户的ip地址列表或指定可连接服务器的服务器ip地址列表。(即白名单验证)

                authenticationRestrictions

字段名称 数据类型 描述
clientSource ip地址数组或CIDR范围 如果存在,则服务器验证客户端的ip地址是否位于给定列表中,或者属于列表中的一个CIDR范围。如果客户端的ip地址不在当前,服务器就不会对用户进行身份验证。
serverAddress ip地址数组或CIDR范围 客户端可以连接的ip地址列表或CIDR范围。如果存在,服务器将验证客户端的连接是否符合给定列表中的ip地址列表或CIDR。如果不符合,则服务器不会对用户进行身份验证

简单来说,clientSource 就是服务器针对客户端的IP 做白名单控制。serverAddress 就是客户端针对服务端的IP 做白名单控制。也就是说,客户端和服务器端都可以维护一个白名单进行限制。

注:如果用户继承了具有不兼容身份验证限制的多个角色,则该用户将无法使用。例如,如果用户继承一个角色的clientSource字段为[“198.51.100.0”]和另一个clientSource字段为[“203.0.113.0”]的角色,服务器无法对用户进行身份验证。

                可分配的用户账号角色
更多可查看官方文档

角色 描述
read 让用户能够读取当前数据库中的任何集合的数据
readAnyDatabase 和read一样能够读取任何集合的数据,不过该用户可以读取任何数据库的,不在是指定数据库
readWrite 用户可以读写当前数据库中的任何集合,读写包括插入、删除、更新文档以及创建、重命名、删除集合
readWriteAnyDatabase 与readWrite权限一样,不过其可以操作所有数据库,不再只能操作指定数据库
dbAdmin 让用户能够读写当前数据库以及清理、修改、压缩、获取统计信息和执行检查
dbAdminAnyDatabase 与dbAdmin权限一样,不过其可以操作所有数据库,不再只能操作指定数据库
dbOwner 数据库所有者可以在数据库上执行任何管理操作。这个角色结合readWrite、dbAdmin、userAdmin
clusterManager 3.4版本以后新特性,提供集群的管理和监视操作。具有此角色的用户可以访问、配置和访问本地数据库,它们分别用于分片和复制中。
clusterMonitor 3.4版本新特性,提供对监视工具的只读访问权限,比如MongoDB Cloud Manager和Ops Manager
hostManager 提供监视和管理服务器的能力。
clusterAdmin 让用户能够管理MongoDB,包括连接、集群、复制、列出数据库、创建数据库、和删除数据库
userAdmin 让用户能够在当前数据库中创建和修改用户账户
userAdminAnyDatabase 与userAdmin相同,过其可以操作所有数据库,不再只能操作指定数据库
backup 3.4新特性,提供备份数据所需的最小权限。该角色有足够的权限使用MongoDB Cloud Manager、Ops Manager的备用代理或者使用mongodump
restore 3.6新特性,提供对非系统集合的转换。提供从备份中恢复数据所需的特权,这些备份不会对数据进行重新配置。当还原数据时,此角色足够。
root 提供对所有资源的访问权限。集合了readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin、backup这些角色的所有权限。
__system mongodb将此角色分配给表示集群成员的用户对象,该角色赋予其持有者对数据库中的任何对象采取任何操作。请将此角色用于代表应用程序或管理员的用户对象,而不是在异常情况下。

上述的用户角色表中,每个用户可以拥有多个角色,即用户可以同时拥有dbAdmin也可以拥有userAdmin

了解了创建用户所需字段,以及角色的权限,那么我们就可以创建用户了

连接到mongooDB shell之后,默认连接的是test数据库,为了演示方便我们,将当前数据库切换到一个专门用于测试用户账号的数据库,名字随便取,如下图所示,切换到了userTest数据库:
这里写图片描述
上图的userTest数据库原本是没有的,我们使用use database命令,会切换到该数据库,如果该数据库不存在则会创建,并切换到该数据库,当然如果该数据库创建完成之后,内部没有添加任何的集合,我们使用show dbs命令,是不会显示的。

切换到useTest,之后我们使用createUser()方法添加一个测试用户,如(注:使用shell输入的时候一定要特别小心,因为坑爹的是shell不能复制粘贴,如果报错,还没有输入记录,只能重新输入):

use userTest
db.createUser( { user: "test",
                 pwd: "test",
                 customData: { employeeId: 12345 },
                 roles: [ "readWrite"] },
               { w: "majority" , wtimeout: 5000 } )

我们创建完一个用户后,可以使用show users或者使用db.getUser(username),db.getUsers()来查看当前数据库的所有用户。如图,我们可以看到我们在设置角色是,若未指定数据库,则其默认当前数据库。
这里写图片描述

为了演示,我们可以创建另一个比较复杂的用户,我们在userTest数据库中创建一个具有admin数据库权限的用户,

use userTest
db.createUser( { user: "test1",
                 pwd: "test1",
                 roles: [{ role: "readAnyDatabase", db: "admin" },
                          "readWrite"] } )

这里写图片描述
可以看到现在userTest有两个用户了,新建的用户具有对admin数据库的读取所有数据库的权限。但是如果我们切换到admin数据库,是看不到该用户的,因为这个用户是数据userTest的,如图:
这里写图片描述

当然我们还可以创建一个没有权限的用户,比如:

db.createUser( { user: "test2",
                 pwd: "test2",
                 roles: [] } )

这里写图片描述

创建需要身份验证白名单的用户:

db.createUser(
   {
     user: "test3",
     pwd: "test3",
     roles: [ ],
     authenticationRestrictions: [ {
        clientSource: ["192.0.2.0"],
        serverAddress: ["198.51.100.0"]
     } ]
   }
)

这里写图片描述
如下图,查看用户时,发现ip限制并没有展示:
这里写图片描述
这个可能是MongoDB的一个疏忽了。

修改用户账号

对于用户的账号的修改维护,MongoDB提供了一些方法,由于方法都比较简单,我这里就不做演示了,下表为方法列表:

方法 描述
db.changeUserPassword(username, password) 修改用户的密码
db.grantRolesToUser(username, roles, writeConcern) 授权用户角色列表
db.revokeRolesFromUser( username, [ roles ], { writeConcern } ) 移除一个用户的一个或多个角色
db.updateRole(rolename, update, writeConcern) 更新用户定义的角色。该方法必须运行在角色的数据库上。该方法会完全覆盖原来的角色配置,如果想要修改某一部分,可以使用角色管理的方法,下篇博文用于介绍MongoDB shell的所有方法

删除用户

删除用户,MongoDB提供了三个方法,

  • db.removeUser(username):这个方法是2.6版本以前的删除用户的方法,2.6版本以后不建议使用,虽然该方法也能够删除用户,但会报不建议使用的警告。
  • db.dropUser(username):这个方法是上个方法的替代方法
  • db.dropAllUsers():删除当前数据的所有用户

注:删除某个数据库的用户,需要先切换到该数据库,否则删除不成功

这里写图片描述

配置访问控制

新安装一个MonoDB数据库,首先要做的事情,就是添加用户账户配置访问控制,MongoDB提供了数据库级的身份验证和授权,这也就意味着用户账户存在于单个数据库中,为支持基本的身份验证,MongoDB在每个数据库中,都将用户凭证存储在admin数据库的集合system.users中。如果想要查询system.users中的数据,需要先切换到admin数据库,然后使用db.admin.users.find(),如:
这里写图片描述

  • 创建超级用户(root)

    如果我们开启数据库的身份验证功能,那么我们首先需要创建一个超级用户,超级用户最起码功能能够创建用户,便于能够登录。
    创建超级用户,我们只需要给它赋予root权限即可,同样,和创建普通用户一致,只不过需要在admin数据库中创建,如图:
    这里写图片描述

  • 启用身份验证
    创建超级管理员之后,我们就可以开启数据库的身份验证了。
    很简单 ,如果是命令行启动,直接启动时加 --auth参数即可。
    如果是配置文件启动,在配置文件中配置auth=true即可。

首先我们需要先关闭当前启动的MongoDB。大家可以参考这篇文章
然后我们修改配置文件,如图:
这里写图片描述

然后使用mongod命令启动服务,或者使用windows服务启动,因为我们的服务已经注册为服务,我们只需要使用net start MongoDB启动服务即可,如图:
这里写图片描述
上图启动成功。

这时候由于开启了身份验证,这时候我们连接MongoDB shell后,在操作数据库的功能,就会提示没有权限操作,如图:
这里写图片描述
这时候我们需要使用db.auth(username,password)来验证身份。验证之后就可以进行对应角色能够操作的功能了。

当然我们也可以在连接MongoDB shell时就可以使用 –username 和 –password 来想数据库校验身份,命令格式为:

mongo ip:port/database --username "username" -- password "password"

如图:这里写图片描述
注:指定的数据库必须是账户所在的数据库,否则会报错,如下图
这里写图片描述

如果大家使用MongoDB Compass连接MongoDB,那么大家就需要输入用户名密码,如图:这里写图片描述
我这边出现这样的一种情况,数据库连接进去了,但是在加载导航栏时,报错,报的是:

An error occurred while loading navigation:there are no users authenticated

说没有权限,但是权限列表中是没有关于MongoDB Compass的相关权限的,顶多也就需要个读写权限。但是读写权限我们的权限是足的。昨天一直报这个连接不上去,也没找到解决方法,但是,今天早上我清理下电脑缓存之后,MongoDB 又能正常连接了。所以我估计是缓存垃圾的问题。大家可以尝试下。

最后注一个想要说的:

如果你在实验的时候,开启了身份验证,但是账号没设置、设置角色错了、密码账号忘记等导致登录不进MongoDB,那么我们有一个解决方法,就是将配置文件中的权限验证给删除掉,重新登录进MongoDB进行相应的修改,该方法仅供非常紧急的时候的解决方法,但是不建议这样做。

猜你喜欢

转载自blog.csdn.net/qq_33206732/article/details/79877948