瑞_MongoDB_安全认证

瑞&3l

🙊 前言:本文章为瑞_系列专栏之《MongoDB》的集群和安全整合篇的 MongoDB 安全认证章节。由于博主是从B站黑马程序员的《MongoDB》学习其相关知识,所以本系列专栏主要是针对该课程进行笔记总结和拓展,文中的部分原理及图解等也是来源于黑马提供的资料,特此注明。本文仅供大家交流、学习及研究使用,禁止用于商业用途,违者必究!

系列整合篇:《瑞_MongoDB(笔记超详细,有这一篇就够了)》
单实例环境部署请参考:《瑞_MongoDB的2.4.2 Linux安装MongoDB》
副本集环境部署请参考:《瑞_MongoDB_MongoDB副本集》
分片集群环境部署请参考:《瑞_MongoDB_MongoDB分片集群》




1 MongoDB副本集-Replica Sets

瑞:副本集的作用就是,当一台服务器挂了,可以无缝切换另一台服务,类似 MySQL 的主从复制,具体请见《瑞_MongoDB_MongoDB副本集》




2 分片集群-Sharded Cluster

瑞:副本集的特点是,无论搭建了多少个副本节点,存储的数据都是一样的,这样就会导致数据只能存在一台服务器上。随着业务量的扩大,一台服务器无法存储海量数据,此时就需要分片集群存储,具体请见《瑞_MongoDB_MongoDB分片集群》




3 安全认证

3.1 MongoDB的用户和角色权限简介

  默认情况下,MongoDB 实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随意连接到实例进行各种操作,MongoDB 不会对连接客户端进行用户验证,这是非常危险的。

  MongoDB 官网上说,为了能保障 MongoDB 的安全可以做以下几个步骤⬇️

  1️⃣ 使用新的端口,默认的 27017 端口如果一旦知道了 ip 就能连接上,不太安全。

  2️⃣ 设置 MongoDB 的网络环境,最好将 MongoDB 部署到公司服务器内网,外网无法访问。公司内部访问使用 vpn 等。

  3️⃣ 开启安全认证。认证要同时设置服务器之间的内部认证方式,同时要设置客户端连接到集群的账号密码认证方式。

  为了强制开启用户访问控制(用户验证),则需要在 MongoDB 实例启动时使用选项--auth或在指定启动配置文件中添加选项auth=true

3.1.1 相关概念

  在开始之前先了解一些相关概念

  • 启用访问控制

  MongoDB使用的是基于角色的访问控制(Role-Based Access Control,RBAC)来管理用户对实例的访问。通过对用户授予一个或多个角色来控制用户访问数据库资源的权限和数据库操作的权限,在对用户分配角色之前,用户无法访问实例。

  在实例启动时添加选项--auth或指定启动配置文件中添加选项auth=true

  • 角色

  在 MongoDB 中通过角色对用户授予相应数据库资源的操作权限,每个角色当中的权限可以显式指定,也可以通过继承其他角色的权限,或者两都都存在的权限。

  • 权限

  权限由指定的数据库资源(resource)以及允许在指定资源上进行的操作(action)组成。

  1️⃣ 资源(resource)包括:数据库、集合、部分集合和集群;

  2️⃣ 操作(action)包括:对资源进行的增、删、改、查(CRUD)操作。

  在角色定义时可以包含一个或多个已存在的角色,新创建的角色会继承包含的角色所有的权限。在同一个数据库中,新创建角色可以继承其他角色的权限,在admin数据库中创建的角色可以继承在其它任意数据库中角色的权限。

3.1.2 角色权限相关命令

  关于角色权限的查看,可以通过如下命令查询(了解)

# 查询所有角色权限(仅用户自定义角色)
> db.runCommand({ rolesInfo: 1 })

# 查询所有角色权限(包含内置角色)
> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })

# 查询当前数据库中的某角色的权限
> db.runCommand({ rolesInfo: "<rolename>" })

# 查询其它数据库中指定的角色权限
> db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }

# 查询多个角色权限
> db.runCommand(
    {
        rolesInfo: [
            "<rolename>",
            { role: "<rolename>", db: "<database>" },
            ...
        ]
    }
)

  【示例】查看所有内置角色

> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })
{
        "roles" : [
                {
                        "role" : "__queryableBackup",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "__system",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "backup",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "clusterAdmin",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "clusterManager",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "clusterMonitor",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "dbAdmin",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "dbAdminAnyDatabase",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "dbOwner",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "enableSharding",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "hostManager",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "read",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "readAnyDatabase",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "readWrite",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "readWriteAnyDatabase",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "restore",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "root",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "userAdmin",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                },
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin",
                        "isBuiltin" : true,
                        "roles" : [ ],
                        "inheritedRoles" : [ ]
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1714337286, 5),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1714337288, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
3.1.3 常用的内置角色

  常用的内置角色

  • 数据库用户角色:read、readWrite;
  • 所有数据库用户角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin;
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
  • 备份恢复角色:backup、restore;
  • 超级用户角色:root
  • 内部角色:system

  角色说明

角色权限描述
read读取指定数据库中任何数据
readWrite读写指定数据库中任何数据,包括创建、重命名、删除集合
readAnyDatabase读取所有数据库中任何数据(除了数据库config和local之外)
readWriteAnyDatabase读写所有数据库中任何数据(除了数据库config和local之外)
userAdminAnyDatabase在指定数据库创建和修改用户(除了数据库config和local之外)
dbAdminAnyDatabase读取任何数据库以及对数据库进行清理、修改、压缩、获取统计信息、执行检查等操作(除了数据库config和local之外)
dbAdmin读取指定数据库以及对数据库进行清理、修改、压缩、获取统计信息、执行检查等操作
userAdmin在指定数据库创建和修改用户
clusterAdmin对整个集群或数据库系统进行管理操作
backup备份MongoDB数据最小的权限
restore从备份文件中还原恢复MongoDB数据(除了system.profile集合)的权限
root超级账号,超级权限

3.2 单实例环境

目标:对单实例的 MongoDB 服务开启安全认证,这里的单实例指的是未开启副本集或分片的 MongoDB 实例

   增加 MongoDB 的单实例的安全认证功能,可以在服务搭建的时候直接添加,也可以在之前搭建好的服务上添加。

   本文使用之前搭建好的服务,Linux 安装 MongoDB 服务可参考本系列《瑞_MongoDB的2.4.2 Linux安装MongoDB》,因此,需要先停止之前的服务(如果你是第一次接触本系列文章,则可跳过关闭服务步骤),如下一小节进行关闭操作

3.2.1 关闭已开启的服务(可选)

   由于本系列之前文章的操作,运行了多个 MongoDB 服务,现在需要关闭已开启的服务,执行ps -ef | grep mongo命令查看 mongo 服务,并执行kill -2 PID PID PID命令杀死 MongoDB 进程,如下图所示

在这里插入图片描述

关闭已开启的 mongo 服务有以下两种方式,上例使用的是方式2️⃣,实际操作时建议使用方式1️⃣

  方法1️⃣ 通过 mongo 客户端中的 shutdownServer 命令来标准关闭服务

# 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行
/usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017
# 切换到admin库
use admin
# 关闭服务
db.shutdownServer()

  显示如下图所示,即成功关闭服务

在这里插入图片描述

  方法2️⃣ 通过系统的kill命令直接杀死 MongoDB 进程,快速关闭服务(快速,简单,但数据可能会出错

# 查询 MongoDB 服务进程PID
ps -ef | grep mongod
# 使用 kill -2 或 kill -9 杀死 MongoDB 服务进程(kill -2 会尝试以优雅的方式终止进程,并允许进程执行清理工作;而 kill -9 则会立即停止进程的运行,不考虑进程的优雅结束或释放资源)
kill -2 3028

在这里插入图片描述

【补充】

  如果一旦数据损坏,可以进行如下操作⬇️
  1️⃣ 删除lock文件:rm -f /usr/local/mongodb/single/data/db/*.lock
  2️⃣ 修复数据:/usr/local/mongodb/bin/mongod --repair --dbpath=/usr/local/mongodb/single/data/db/

3.2.2 添加用户和权限

单实例环境即 Linux 安装 MongoDB 服务,可参考本系列《瑞_MongoDB的2.4.2 Linux安装MongoDB》

  1️⃣ 按照普通无授权认证的配置,来配置服务端的配置文件/usr/local/mongodb/single/mongod.conf(复用之前的文章)

systemLog:
 # MongoDB发送所有日志输出的目标指定为文件
 # The path of the log file to which mongod or mongos should send all diagnostic logging information
 destination: file
 # mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
 path: "/usr/local/mongodb/single/log/mongod.log"
 # 当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
 logAppend: true
storage:
 # mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
 ##The directory where the mongod instance stores its data.Default Value is "/data/db".
 dbPath: "/usr/local/mongodb/single/data/db"
 journal:
  # 启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  enabled: true
processManagement:
 # 启用在后台运行mongos或mongod进程的守护进程模式。
 fork: true
net:
 # 服务实例绑定的IP,默认是localhost
 bindIp: localhost,192.168.133.131
 # bindIp
 # 绑定的端口,默认是27017
 port: 27017

  2️⃣ 按之前未开启认证的方式(不添加--auth参数)来启动 MongoDB 服务

建议:在操作用户时,启动 mongod 服务时尽量不要开启授权,尽量使用配置文件方式代替参数启动

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/single/mongod.conf
# 或
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/single/mongod.conf

在这里插入图片描述

  3️⃣ 使用 Mongo 客户端登录

/usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017

在这里插入图片描述

  4️⃣ 创建两个管理员用户,一个是系统的超级管理员myroot,一个是 admin 库的管理用户myadmin

# 查看数据库
> show dbs
admin      0.000GB
articledb  0.000GB
config     0.000GB
local      0.000GB
rayTest    0.000GB
# 切换到admin库
> use admin
switched to db admin
# 确认已切换到admin库
> db
admin
# 创建系统超级用户 myroot,设置密码123456,设置角色root
# > db.createUser({user:"myroot",pwd:"123456",roles:[ { "role" : "root", "db" :"admin" } ]})
# 或
> db.createUser({user:"myroot",pwd:"123456",roles:["root"]})
Successfully added user: { "user" : "myroot", "roles" : [ "root" ] }
# 创建专门用来管理admin库的账号myadmin,只用来作为用户权限的管理
> db.createUser({user:"myadmin",pwd:"123456",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
Successfully added user: {
        "user" : "myadmin",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                }
        ]
}
# 查看已经创建了的用户的情况
> db.system.users.find()
{ "_id" : "admin.myroot", "userId" : UUID("ebcc96af-56be-40c4-accc-122fd5c8d0f6"), "user" : "myroot", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "pSQvpKqaguK16dOjQh/WUw==", "storedKey" : "NLtcyxvrm6csgvwudvnP3rxvS0g=", "serverKey" : "j0ONQ+1Ny/ZEmEhHkQHo/n4B7X0=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "JxSQhmOUBLkyg4xuIi4uxqIaPMxzrDOHWRc16A==", "storedKey" : "05U7LHA/43k5AlkMxRp81F9TThdsMgnUE0k+iCGI9tM=", "serverKey" : "Q2iijziAWotJ70bi/a4Njt5FssDu9yXBsz3515LxOQA=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ] }
{ "_id" : "admin.myadmin", "userId" : UUID("653e4032-8b5c-44d3-a0e2-f55474f44472"), "user" : "myadmin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "Cl79GxxPiwF4viOKiwcmBA==", "storedKey" : "EbCqEejCEIUPWiMuYMVFJxfluBc=", "serverKey" : "VVyZc3Q7EyDl/MSW2xPzOjzNluE=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "/O+Ni20QBWeWYScYlO5Zbp685vHee+e/kCDsHA==", "storedKey" : "9ajUY9VGDn6wduIM8+Wt3r6UZAfr/OIkPDUVoqnEN2Y=", "serverKey" : "EEZOLSJGO4FqdT+WWrn3cS182rcgzfS5VfYgYTG6DAQ=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
# 删除用户myadmin
> db.dropUser("myadmin")
true
# 确认用户myadmin被删除
> db.system.users.find()
{ "_id" : "admin.myroot", "userId" : UUID("ebcc96af-56be-40c4-accc-122fd5c8d0f6"), "user" : "myroot", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "pSQvpKqaguK16dOjQh/WUw==", "storedKey" : "NLtcyxvrm6csgvwudvnP3rxvS0g=", "serverKey" : "j0ONQ+1Ny/ZEmEhHkQHo/n4B7X0=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "JxSQhmOUBLkyg4xuIi4uxqIaPMxzrDOHWRc16A==", "storedKey" : "05U7LHA/43k5AlkMxRp81F9TThdsMgnUE0k+iCGI9tM=", "serverKey" : "Q2iijziAWotJ70bi/a4Njt5FssDu9yXBsz3515LxOQA=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ] }
>
# 修改密码
> db.changeUserPassword("myroot", "123456")

在这里插入图片描述

角色userAdminAnyDatabase说明:在指定数据库创建和修改用户(除了数据库 config 和 local 之外)

  【提示】

  1. 本案例创建了两个用户,分别对应超管和专门用来管理用户的角色,事实上,你只需要一个用户即可。如果你对安全要求很高,防止超管泄漏,则不要创建超管用户。
  2. 和其它数据库(如 MySQL)一样,权限的管理都差不多一样,也是将用户和权限信息保存到数据库对应的表中。MongoDB 存储所有的用户信息在 admin 数据库的集合system.users中,保存用户名、密码和数据库信息。
  3. 如果不指定数据库,则创建的指定的权限的用户在所有的数据库上有效,如{role:"userAdminAnyDatabase", db:""}

  5️⃣ 认证测试,测试添加的用户是否正确

# 切换到admin
> use admin
# 密码故意输错
> db.auth("myroot","ray")
Error: Authentication failed.
0
# 输入正确的密码
> db.auth("myroot","123456")
1

在这里插入图片描述

瑞:在一般情况下,不建议直接使用超级管理员用户去操作,因为相当危险,所以一般情况下还会创建一个权限相对小的普通用户,并使用普通用户进行操作某个具体的数据库

  6️⃣ 创建普通用户

  创建普通用户可以在没有开启认证的时候添加,也可以在开启认证之后添加,但开启认证之后,必须使用有操作 admin 库的用户登录认证后才能操作。底层都是将用户信息保存在了 admin 数据库的集合system.users中。

# 创建(切换)将来要操作的数据库articledb,如果你没有的话请先创建该数据库
> use articledb
switched to db articledb
# 创建用户,拥有articledb数据库的读写权限readWrite,密码是123456
> db.createUser({user: "ray", pwd: "123456", roles: [{ role: "readWrite", db:"articledb" }]})
Successfully added user: {
        "user" : "ray",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "articledb"
                }
        ]
}
# 测试是否可用
> db.auth("ray","123456")
1

在这里插入图片描述

提示:如果开启了认证后,登录的客户端的用户必须使用 admin 库的角色,如拥有 root 角色的 myadmin 用户,再通过 myadmin 用户去创建其他角色的用户

3.2.3 服务端开启认证和客户端连接登录

由于服务端启动的时候没有添加开启认证的操作命令,所以当前不用登录用户依然可以直接操作。如果想要登录用户后才能进行操作,则需要进行以下操作

  1️⃣ 关闭已经启动的服务。执行ps -ef | grep mongo命令查看 mongo 服务,并执行kill -2 PID命令杀死 MongoDB 进程,如下图所示

在这里插入图片描述

  2️⃣ 以服务端开启认证的方式启动服务

  有两种方式开启权限认证启动服务:一种是参数方式,一种是配置文件方式

3.2.3.1 服务端开启认证——参数方式

  在启动时指定参数--auth

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/single/mongod.conf --auth

瑞:以参数方式开启认证在开发当中很少使用。因为这种方式必须要每次启动的时候带上参数,如果哪一次忘了,就相当于安全认证不起作用,非常不安全,操作不严谨。

3.2.3.2 服务端开启认证——配置文件方式(推荐)

  在mongod.conf配置文件中加入开启授权认证的配置

  使用vi /usr/local/mongodb/single/mongod.conf编辑配置文件

瑞:指令使用:按a切换到输入状态,将下面配置文件内容复制过去,然后按esc输入:wq保存文件并退出

  添加如下配置

security:
 # 开启授权认证
 authorization: enabled

在这里插入图片描述

  启动时可不加--auth参数

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/single/mongod.conf

  此时连接客户端,发现可以正常连接,但无操作权限,如下图执行show dbs后啥也看不见

/usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017

在这里插入图片描述

  开启认证后再登录,打印的日志会有所减少。相关操作需要认证后才可以执行成功。


  开启了认证的情况下的客户端登录,有两种认证方式

  1️⃣ 先连接登录,再在 mongo shell 中认证

  2️⃣ 登录时直接认证

3.2.4.3 客户端连接登录——先连接再认证

  连接客户端

/usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017

  再在相应的数据库中使用 mongo shell 进行认证

  【示例1】使用use admin数据库进行 myroot 角色(超级管理员)认证

[root@localhost ~]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("98afb9e9-b56c-4f3e-a9df-8f573871e252") }
MongoDB server version: 4.0.10
> show dbs
>
> use admin
switched to db admin
> db.auth("myroot","123456")
1
> show dbs
admin      0.000GB
articledb  0.000GB
config     0.000GB
local      0.000GB
rayTest    0.000GB
> db
admin
> show collections
system.users
system.version
> db.system.users.find()
..输出省略..

在这里插入图片描述


  【示例2】使用use articledb数据库进行 ray 角色(普通用户)认证

[root@localhost ~]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("1d248426-e70e-4204-9820-1ac0bca2f2e8") }
MongoDB server version: 4.0.10
> show dbs
>
> use articledb
switched to db articledb
> db.auth("ray","123456")
1
> show collections
comment
> show dbs
articledb  0.000GB

在这里插入图片描述

瑞:注意一定要到相应的数据库中进行认证操作,如use adminuse articledb,默认使用 test 数据库,则会报 Error: Authentication failed.

在这里插入图片描述

3.2.4.4 客户端连接登录——连接时直接认证

  【参数说明】

  • -u:用户名
  • -p:密码
  • --authenticationDatabase:指定连接到哪个库。当登录是指定用户名密码时,必须指定对应的数据库

  【示例1】对 admin 数据库进行登录认证和相关操作

[root@localhost ~]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017 --authenticationDatabase admin -u myroot -p 123456
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?authSource=admin&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("069db1cb-6450-4a81-8cd4-7da8cc76c16e") }
MongoDB server version: 4.0.10
Server has startup warnings:
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten]
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten]
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten]
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2024-07-13T16:16:21.355+0800 I CONTROL  [initandlisten]
> show dbs
admin      0.000GB
articledb  0.000GB
config     0.000GB
local      0.000GB
rayTest    0.000GB

在这里插入图片描述


  【示例2】对 articledb 数据库进行登录认证和相关操作

[root@localhost ~]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017 --authenticationDatabase articledb -u ray -p 123456
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?authSource=articledb&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5583875f-f8bc-4cec-b112-5702df4ce326") }
MongoDB server version: 4.0.10
> show dbs
articledb  0.000GB
>

在这里插入图片描述

3.2.4 SpringDataMongoDB连接认证

  相关案例代码可参考《瑞_MongoDB_案例-文章评论》

  article【瑞_MongoDB_案例-文章评论】的完整源码的某度网盘链接如下,需要自取

链接:https://pan.baidu.com/s/1FMNAZNkXYm8kSbv18A6RDw?pwd=a7r4
提取码:a7r4


  使用用户名和密码连接到 MongoDB 服务器,你必须使用'username:password@hostname/dbname'格式,username为用户名,password为密码

  【示例】使用用户 ray 使用密码 123456 连接到 MongoDB 服务上

  application.yml添加配置,可参考如下

spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
#      host: 192.168.133.131
      # 数据库
#      database: articledb
      # 默认端口是27017
#      port: 27017
      # 帐号
#      username: ray
      # 密码(如果密码是纯数字要加上'')
#      password: '123456'
      # 方式二:使用uri连接
#      uri: mongodb://192.168.133.131:27017/articledb
      # 副本集的连接字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27018,192.168.133.131:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
      # 连接路由字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27117/articledb
      # 单机有设置安全认证的情况下,使用字符串连接
      uri: mongodb://ray:123456@192.168.133.131:27017/articledb

  在CommentServiceTest测试类中选择一个测试用例,如查询所有数据的方法testFindAll()进行测试,如下图测试通过即配置成功

在这里插入图片描述

  使用 Compass 的时候要选择使用用户名密码连接,并输入认证数据库

在这里插入图片描述

3.3 副本集环境

  对于搭建好的 MongoDB 副本集,为了安全,启动安全认证,使用账号密码登录

瑞:和单实例环境配置基本一致,区别在于要创建和配置 keyfile 密钥文件

3.3.1 前言

  本文副本集环境使用之前本系列章节中《瑞_MongoDB_MongoDB副本集》搭建好的,架构如下图所示

在这里插入图片描述

  对副本集执行访问控制需要配置两个方面

  1️⃣ 副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件(keyfile)或 x.509 证书。密钥文件比较简单,本文使用密钥文件,官方推荐如果是测试环境可以使用密钥文件,但是正式环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问。

  2️⃣ 使用客户端连接到 MongoDB 集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。

  在 keyfile 身份验证中,副本集中的每个 实例都使用 MongoDB 的内容作为共享密码,只有具有正确密钥文件的 mongod 或者 mongos 实例可以连接到副本集。密钥文件的内容必须在 6 到 1024 个字符之间,并且在 unix/linux 系统中文件所有者必须有对文件至少有读的权限。

3.3.2 关闭已开启的副本集服务(可选)

  增加副本集的安全认证和服务鉴权功能,可以在副本集搭建的时候直接添加,也可以在之前搭建好的副本集服务上添加。

   本文使用之前搭建好的服务,Linux 安装 MongoDB 副本集可参考本系列《瑞_MongoDB_MongoDB副本集》,因此,需要先停止之前的集群服务(如果你是第一次接触本系列文章,则可跳过关闭服务步骤),如下进行关闭操作

   由于本系列之前文章的操作,运行了多个 MongoDB 服务,现在需要关闭已开启的服务,执行ps -ef | grep mongo命令查看 mongo 服务,并执行kill -2 PID PID PID命令杀死 MongoDB 进程,如下图所示

在这里插入图片描述

关闭已开启的 mongo 服务有两种方式,点我跳转回顾,上例使用的是方式2️⃣,实际操作时建议使用方式1️⃣

  标准关闭副本集中的服务,建议依次关闭仲裁节点、副本节点、主节点。主要的操作步骤参考如下

# 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
# 告知副本集说本机要下线
rs.stepDown()
# 切换到admin库
use admin
# 关闭服务
db.shutdownServer()

在实际情况中,如果副本集是开启状态,则先分别关闭关闭副本集中的每个 mongod,从次节点开始。直到副本集的所有成员都离线,包括任何仲裁者。主节点必须是最后一个成员关闭以避免潜在的回滚。

3.3.3 通过主节点添加一个管理员帐号

只需要在主节点上添加用户,副本集会自动同步

  1️⃣ 分别启动副本集的 3 个节点,组成副本集环境

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf

在这里插入图片描述

  2️⃣ 登录主节点客户端

/usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017

  3️⃣ 开启认证之前,创建超管用户:myroot,密码:123456

# 切换到admin库
myrs:PRIMARY> use admin
switched to db admin
# 创建系统超级用户 myroot,设置密码123456,设置角色root
myrs:PRIMARY> db.createUser({user:"myroot",pwd:"123456",roles:["root"]})
Successfully added user: { "user" : "myroot", "roles" : [ "root" ] }
myrs:PRIMARY>

在这里插入图片描述

瑞:详细步骤解释详可参考本文单实例环境的添加用户和权限的相关部分

3.3.4 创建副本集认证的key文件

  1️⃣ 生成一个 key 文件到当前文件夹中(当前文件夹建议使用副本集目录,如博主为/usr/local/mongodb/replica_sets/

  可以使用任何方法生成密钥文件。例如,以下操作使用 openssl 生成密码文件,然后使用 chmod 来更改文件权限,仅为文件所有者提供读取权限

# 进入副本集目录
[root@localhost ~]# cd /usr/local/mongodb/replica_sets/
# 使用 openssl 生成密码文件
[root@localhost replica_sets]# openssl rand -base64 90 -out ./mongo.keyfile
# 更改文件权限,仅为文件所有者提供读取权限
[root@localhost replica_sets]# chmod 400 ./mongo.keyfile
# 查看
[root@localhost replica_sets]# ll mongo.keyfile
-r--------. 1 root root 122 713 19:23 mongo.keyfile

在这里插入图片描述

  【提示】

  所有副本集节点都必须要用同一份 keyfile,一般是在一台机器上生成,然后拷贝到其他机器上,且必须有读的权限,否则将来会报错: permissions on /usr/local/mongodb/replica_sets/myrs_27017/mongo.keyfile are too open

  2️⃣ 一定要保证 keyfile 密钥文件是一致的,文件位置随便。但是为了方便查找,建议每台机器都放到一个固定的位置,都放到和配置文件一起的目录中。博主将该文件分别拷贝到多个节点目录中

# 进入副本集目录
[root@localhost ~]# cd /usr/local/mongodb/replica_sets/
# 拷贝文件
[root@localhost replica_sets]# cp mongo.keyfile /usr/local/mongodb/replica_sets/myrs_27017
[root@localhost replica_sets]# cp mongo.keyfile /usr/local/mongodb/replica_sets/myrs_27018
[root@localhost replica_sets]# cp mongo.keyfile /usr/local/mongodb/replica_sets/myrs_27019
3.3.5 修改配置文件指定keyfile

  分别编辑几个节点服务的mongod.conf文件,在配置文件中添加相关内容

/usr/local/mongodb/replica_sets/myrs_27017/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/replica_sets/myrs_27017/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

在这里插入图片描述

/usr/local/mongodb/replica_sets/myrs_27018/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/replica_sets/myrs_27018/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

/usr/local/mongodb/replica_sets/myrs_27019/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/replica_sets/myrs_27019/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled
3.3.6 重新启动副本集

  由于之前将副本集开启了,运行了多个 MongoDB 服务,先分别关闭副本集中的每个 MongoDB 服务,从次节点开始。直到副本集的所有成员都离线,包括任何仲裁者。主节点必须是最后一个成员关闭以避免潜在的回滚。

  执行ps -ef | grep mongo命令查看 mongo 服务,并执行kill -2 PID PID PID命令杀死 MongoDB 进程,建议依次杀死仲裁节点、副本节点、主节点,如下图所示

在这里插入图片描述

关闭已开启的 mongo 服务有两种方式,点我跳转回顾,上例使用的是方式2️⃣,实际操作时建议使用方式1️⃣

  分别启动副本集的 3 个节点

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf

  执行ps -ef |grep mongod命令查看进程情况

在这里插入图片描述

3.3.7 在主节点上添加普通账号

  在主节点上添加普通账号,副本节点也会同步复制

# 登录主节点客户端
[root@localhost replica_sets]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("7a32ce4d-6a52-4728-9fdc-8db91477fb35") }
MongoDB server version: 4.0.10
myrs:PRIMARY>
# 无权限操作演示
myrs:PRIMARY> show dbs
myrs:PRIMARY>
# 先用管理员账号登录
# 切换到admin库
myrs:PRIMARY> use admin
switched to db admin
# 管理员账号认证
myrs:PRIMARY> db.auth("myroot","123456")
1
# 认证后有权限操作数据库演示
myrs:PRIMARY> show dbs
admin      0.000GB
articledb  0.000GB
config     0.000GB
local      0.001GB
test       0.000GB
myrs:PRIMARY>
# 切换到要认证的库
myrs:PRIMARY> use articledb
switched to db articledb
# 添加普通用户ray
myrs:PRIMARY> db.createUser({user: "ray", pwd: "123456", roles: ["readWrite"]})
Successfully added user: { "user" : "ray", "roles" : [ "readWrite" ] }
myrs:PRIMARY>
# 切换到admin库
myrs:PRIMARY> use admin
switched to db admin
# 查看普通用户是否添加成功
myrs:PRIMARY> db.system.users.find()
..数据省略..

在这里插入图片描述

  重新连接,使用普通用户 ray 重新登录,查看数据。也可以使用rs.status()命令查看副本集是否健康

# 退出连接
myrs:PRIMARY> exit
bye
# 重新连接
[root@localhost replica_sets]# /usr/local/mongodb/bin/mongo --host=192.168.133.131 --port=27017
MongoDB shell version v4.0.10
connecting to: mongodb://192.168.133.131:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("938dd50a-d18c-4bed-9a50-77cb476f1701") }
MongoDB server version: 4.0.10
# 切换到articledb库
myrs:PRIMARY> use articledb
switched to db articledb
# 登录普通用户
myrs:PRIMARY> db.auth("ray","123456")
1
# 操作演示
myrs:PRIMARY> show dbs
articledb  0.000GB
# 操作演示
myrs:PRIMARY> show collections
comment
# 状态查看
myrs:PRIMARY> rs.status()
{
        "operationTime" : Timestamp(1720872863, 1),
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { replSetGetStatus: 1.0, lsid: { id: UUID(\"938dd50a-d18c-4bed-9a50-77cb476f1701\") }, $clusterTime: { clusterTime: Timestamp(1720872843, 1), signature: { hash: BinData(0, 2C2EFBD07CCC7165AD33AF696877C266A7986688), keyId: 7362272470235086849 } }, $db: \"admin\" }",
        "code" : 13,
        "codeName" : "Unauthorized",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1720872863, 1),
                "signature" : {
                        "hash" : BinData(0,"n9mWARREOq84pAvEb02WDQ7xTYk="),
                        "keyId" : NumberLong("7362272470235086849")
                }
        }
}
myrs:PRIMARY>

在这里插入图片描述

3.3.8 SpringDataMongoDB连接副本集

  相关案例代码可参考《瑞_MongoDB_案例-文章评论》

  article【瑞_MongoDB_案例-文章评论】的完整源码的某度网盘链接如下,需要自取

链接:https://pan.baidu.com/s/1FMNAZNkXYm8kSbv18A6RDw?pwd=a7r4
提取码:a7r4


  使用用户名和密码连接到 MongoDB 服务器,你必须使用'username:password@hostname/dbname'格式,username为用户名,password为密码

  【示例】使用用户 ray 使用密码 123456 连接到 MongoDB 服务上

  application.yml添加配置,可参考如下

spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
#      host: 192.168.133.131
      # 数据库
#      database: articledb
      # 默认端口是27017
#      port: 27017
      # 帐号
#      username: ray
      # 密码(如果密码是纯数字要加上'')
#      password: '123456'
      # 方式二:使用uri连接
#      uri: mongodb://192.168.133.131:27017/articledb
      # 副本集的连接字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27018,192.168.133.131:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
      # 连接路由字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27117/articledb
      # 单机有设置安全认证的情况下,使用字符串连接
#      uri: mongodb://ray:123456@192.168.133.131:27017/articledb
      # 副本集有认证的情况下,字符串连接
      uri: mongodb://ray:123456@192.168.133.131:27017,192.168.133.131:27018,192.168.133.131:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs

  在CommentServiceTest测试类中选择一个测试用例,如查询所有数据的方法testFindAll()进行测试,如下图测试通过即配置成功

在这里插入图片描述

3.4 分片集群环境

瑞:和副本集环境配置基本一致,区别在于有更多的节点服务需要配置

  分片集群的服务器环境和架构较为复杂,建议在搭建分片集群的时候,直接加入安全认证和服务器间的鉴权,如果之前有数据,可先将之前的数据备份出来,再还原回去。

  本文分片集群环境使用之前本系列章节中《瑞_MongoDB_MongoDB分片集群》搭建好的

3.4.1 关闭已开启的集群服务(可选)

   由于本系列之前文章的操作,运行了多个 MongoDB 服务,现在需要关闭已开启的服务,执行ps -ef | grep mongo命令查看 mongo 服务,并执行kill -2 PID PID PID命令杀死 MongoDB 进程,如下图所示

在这里插入图片描述

关闭已开启的 mongo 服务有两种方式,点我跳转回顾,上例使用的是方式2️⃣,实际操作时建议使用方式1️⃣

  标准关闭分片服务器副本集中的服务,建议依次关闭仲裁节点、副本节点、主节点。主要的操作步骤参考如下

# 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27018
# 告知副本集说本机要下线
rs.stepDown()
# 切换到admin库
use admin
# 关闭服务
db.shutdownServer()

  标准关闭配置服务器副本集的服务,建议依次关闭副本节点、主节点。主要的操作步骤参考如下

# 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27019
# 告知副本集说本机要下线
rs.stepDown()
# 切换到admin库
use admin
# 关闭服务
db.shutdownServer()

  标准关闭路由服务器的服务,建议依次关闭两个路由节点。主要的操作步骤参考如下

# 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
# 告知副本集说本机要下线
rs.stepDown()
# 切换到admin库
use admin
# 关闭服务
db.shutdownServer()
3.4.2 创建分片集群认证的key文件

  1️⃣ 生成一个 key 文件到当前文件夹中(当前文件夹建议使用分片集群目录,如博主为/usr/local/mongodb/sharded_cluster/

  可以使用任何方法生成密钥文件。例如,以下操作使用 openssl 生成密码文件,然后使用 chmod 来更改文件权限,仅为文件所有者提供读取权限

# 进入副本集目录
[root@localhost ~]# cd /usr/local/mongodb/sharded_cluster/
# 使用 openssl 生成密码文件
[root@localhost sharded_cluster]# openssl rand -base64 90 -out ./mongo.keyfile
# 更改文件权限,仅为文件所有者提供读取权限
[root@localhost sharded_cluster]# chmod 400 ./mongo.keyfile
# 查看
[root@localhost sharded_cluster]# ll mongo.keyfile
-r--------. 1 root root 122 713 19:23 mongo.keyfile

在这里插入图片描述

  【提示】

  所有分片集群节点都必须要用同一份 keyfile,一般是在一台机器上生成,然后拷贝到其他机器上,且必须有读的权限,否则将来会报错: permissions on /usr/local/mongodb/sharded_cluster/myrs_27017/mongo.keyfile are too open

  2️⃣ 一定要保证 keyfile 密钥文件是一致的,文件位置随便。但是为了方便查找,建议每台机器都放到一个固定的位置,都放到和配置文件一起的目录中。博主将该文件分别拷贝到多个节点目录中

# 进入分片集群目录
[root@localhost ~]# cd /usr/local/mongodb/sharded_cluster/
# 拷贝文件
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs01_27018/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs01_27118/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs01_27218/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs02_27318/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs02_27418/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myshardrs02_27518/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myconfigrs_27019/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myconfigrs_27119/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/myconfigrs_27219/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/mymongos_27017/mongo.keyfile
[root@localhost sharded_cluster]# cp mongo.keyfile /usr/local/mongodb/sharded_cluster/mymongos_27117/mongo.keyfile
3.4.3 修改配置文件指定keyfile

  分别编辑几个节点服务的mongod.conf文件,在配置文件中添加相关内容

  1️⃣ /usr/local/mongodb/sharded_cluster/myshardrs01_27018/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs01_27018/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  2️⃣ /usr/local/mongodb/sharded_cluster/myshardrs01_27118/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs01_27118/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  3️⃣ /usr/local/mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs01_27218/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  4️⃣ /usr/local/mongodb/sharded_cluster/myshardrs02_27318/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs02_27318/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  5️⃣ /usr/local/mongodb/sharded_cluster/myshardrs02_27418/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs02_27418/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  6️⃣ /usr/local/mongodb/sharded_cluster/myshardrs02_27518/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myshardrs02_27518/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  7️⃣ /usr/local/mongodb/sharded_cluster/myconfigrs_27019/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myconfigrs_27019/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  8️⃣ /usr/local/mongodb/sharded_cluster/myconfigrs_27119/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myconfigrs_27119/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  9️⃣ /usr/local/mongodb/sharded_cluster/myconfigrs_27219/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/myconfigrs_27219/mongo.keyfile
 # 开启认证方式运行
 authorization: enabled

  1️⃣0️⃣/usr/local/mongodb/sharded_cluster/mymongos_27017/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/mymongos_27017/mongo.keyfile

  1️⃣1️⃣/usr/local/mongodb/sharded_cluster/mymongos_27117/mongod.conf

security:
 # KeyFile鉴权文件
 keyFile: /usr/local/mongodb/sharded_cluster/mymongos_27117/mongo.keyfile

  【注意】

  • mongos 比 mongod 少了 authorization: enabled的配置。原因是,副本集加分片的安全认证需要配置两方面的,副本集各个节点之间使用内部身份验证,用于内部各个 mongo 实例的通信,只有相同 keyfile 才能相互访问。所以都要开启 keyFile: /usr/local/mongodb/sharded_cluster/路径/mongo.keyfile
  • 然而对于所有的 mongod,才是真正的保存数据的分片。mongos 只做路由,不保存数据。所以所有的 mongod 开启访问数据的授权 authorization: enabled。这样用户只有账号密码正确才能访问到数据。
3.4.4 重新启动节点

  启动顺序:必须依次启动配置节点、分片节点、路由节点

/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27019/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27119/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myconfigrs_27219/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27018/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27118/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs01_27218/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27318/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27418/mongod.conf
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/sharded_cluster/myshardrs02_27518/mongod.conf
/usr/local/mongodb/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27017/mongos.conf
/usr/local/mongodb/bin/mongos -f /usr/local/mongodb/sharded_cluster/mymongos_27117/mongos.conf

在这里插入图片描述

  【注意】如果先启动分片节点,会卡住,会提示如下

about to fork child process, waiting until server is ready for connections

  解决方案未知(可能是bug)

3.4.5 创建帐号和认证

瑞:和副本集环境不同,必须通过 localhost 登录任意一个 mongos 路由

  客户端连接 mongo,通过 localhost 登录任意一个 mongos 路由,例如 27017

/usr/local/mongodb/bin/mongo --port 27017

  【提示】此处相当于一个后门,只能在admin下添加用户

  创建一个管理员帐号

[root@localhost sharded_cluster]# /usr/local/mongodb/bin/mongo --port 27017
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("ebb0be23-a29c-45d4-98c8-cc95d70f2b57") }
MongoDB server version: 4.0.10
mongos>
mongos> show dbs
mongos>
mongos> use admin
switched to db admin
mongos> db.createUser({user:"myroot",pwd:"123456",roles:["root"]})
Successfully added user: { "user" : "myroot", "roles" : [ "root" ] }
mongos>

  【提示】如果在开启认证之前已经创建了管理员账号,这里可以忽略

  创建一个普通权限帐号

[root@localhost sharded_cluster]# /usr/local/mongodb/bin/mongo --port 27017
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("8d167461-35a2-41ea-b274-113d27922182") }
MongoDB server version: 4.0.10
mongos> show dbs
mongos>
mongos> use admin
switched to db admin
mongos> db.auth("myroot","123456")
1
mongos> show dbs
admin      0.000GB
articledb  0.001GB
config     0.002GB
mongos> use articledb
switched to db articledb
mongos> db.createUser({user: "ray", pwd: "123456", roles: [{ role: "readWrite",db: "articledb" }]})
Successfully added user: {
        "user" : "ray",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "articledb"
                }
        ]
}
mongos>
mongos> use articledb
switched to db articledb
mongos> db.auth("ray","123456")
1
mongos> 

  【提示】

  通过 mongos 添加的账号信息,只会保存到配置节点的服务中,具体的数据节点不保存账号信息,因此,分片中的账号信息不涉及到同步问题

  mongo 客户端登录 mongos 路由,用管理员帐号登录可查看分片情况

[root@localhost sharded_cluster]# /usr/local/mongodb/bin/mongo --port 27017
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("f72e4ad8-55d7-4873-b825-6d2a138a6854") }
MongoDB server version: 4.0.10
mongos> use admin
switched to db admin
mongos> db.auth("myroot","123456")
1
mongos> sh.status()
..省略..

  退出连接,重新连接服务,使用普通权限帐号访问数据

[root@localhost sharded_cluster]# /usr/local/mongodb/bin/mongo --port 27017
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9fc70806-8a92-4822-bff0-8e27c68e660d") }
MongoDB server version: 4.0.10
mongos> use articledb
switched to db articledb
mongos> db.auth("ray","123456")
1
mongos> show collections
author
comment
mongos> db.comment.count()
1000
mongos>
3.4.6 SpringDataMongoDB连接认证

  相关案例代码可参考《瑞_MongoDB_案例-文章评论》

  article【瑞_MongoDB_案例-文章评论】的完整源码的某度网盘链接如下,需要自取

链接:https://pan.baidu.com/s/1FMNAZNkXYm8kSbv18A6RDw?pwd=a7r4
提取码:a7r4


  使用用户名和密码连接到 MongoDB 服务器,你必须使用'username:password@hostname/dbname'格式,username为用户名,password为密码

  【示例】使用用户 ray 使用密码 123456 连接到 MongoDB 服务上

  application.yml添加配置,可参考如下

spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
#      host: 192.168.133.131
      # 数据库
#      database: articledb
      # 默认端口是27017
#      port: 27017
      # 帐号
#      username: ray
      # 密码(如果密码是纯数字要加上'')
#      password: '123456'
      # 方式二:使用uri连接
#      uri: mongodb://192.168.133.131:27017/articledb
      # 副本集的连接字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27018,192.168.133.131:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
      # 连接路由字符串
#      uri: mongodb://192.168.133.131:27017,192.168.133.131:27117/articledb
      # 单机有设置安全认证的情况下,使用字符串连接
#      uri: mongodb://ray:123456@192.168.133.131:27017/articledb
      # 副本集有认证的情况下,字符串连接
#      uri: mongodb://ray:123456@192.168.133.131:27017,192.168.133.131:27018,192.168.133.131:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
    # 分片集群有认证的情况下,连接路由字符串
      uri: mongodb://ray:123456@192.168.133.131:27017,192.168.133.131:27117/articledb

  在CommentServiceTest测试类中选择一个测试用例,如查询所有数据的方法testFindAll()进行测试,如下图测试通过即配置成功

在这里插入图片描述




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 MongoDB 中,可以使用聚合管道来进行多表查询。聚合管道是一种操作数据的框架,可以在多个阶段对数据进行转换和处理。下面是一个使用 MongoDB 聚合管道进行多表查询的示例: 假设我们有两个集合,一个是用户集合(users),一个是订单集合(orders)。每个订单都对应一个用户。我们想要查询所有订单,并将其对应的用户信息也一并返回。 1. 首先,在 orders 集合中添加一个字段 userId,表示该订单对应的用户 ID。 2. 使用聚合管道进行查询,具体步骤如下: a. 使用 $lookup 阶段连接 users 集合和 orders 集合,将 orders 中的 userId 与 users 中的 _id 进行匹配。$lookup 阶段会将匹配的用户信息添加到每个订单文档中。 b. 使用 $unwind 阶段展开 orders 集合中的数组字段(如果有的话)。 c. 使用 $project 阶段选择要返回的字段,可以同时选择 orders 和 users 集合中的字段。 d. 使用 $match 阶段筛选符合条件的订单,可以根据订单状态、时间等条件进行筛选。 下面是一个示例代码: ``` db.orders.aggregate([ { $lookup: { from: "users", localField: "userId", foreignField: "_id", as: "user" } }, { $unwind: "$items" }, { $project: { _id: 1, userId: 1, status: 1, total: { $sum: "$items.price" }, user: { $arrayElemAt: [ "$user", 0 ] } } }, { $match: { status: "completed" } } ]) ``` 这个查询会返回所有状态为 completed 的订单,每个订单文档中都包含一个 user 子文档,其中包含该订单对应的用户信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑞486

你的点赞评论收藏才更是动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值