当前位置: 首页 >  互联网技术 >  MongoDB 6.0 单实例基于用户角色实现授权登录

MongoDB 6.0 单实例基于用户角色实现授权登录

导读:现代数据库系统能够存储和处理大量数据。因此,由任何一个用户单独负责处理与管理数据库相关的所有活动的情况相对较少。通常,不同的数据库用户需要对数据库的某些部分具有不同级别的访问权限:某些用户可能只需要读取特定数据库中的数据,而其他用户则必须能够插入新文档或修改现有文档。同样,应用程

现代数据库系统能够存储和处理大量数据。因此,由任何一个用户单独负责处理与管理数据库相关的所有活动的情况相对较少。通常,不同的数据库用户需要对数据库的某些部分具有不同级别的访问权限:某些用户可能只需要读取特定数据库中的数据,而其他用户则必须能够插入新文档或修改现有文档。同样,应用程序可能需要独特的权限,仅允许其访问其运行所需的数据库部分。

MongoDB采用强大的机制来控制对数据库系统的访问和权限,称为基于角色的访问控制(RBAC)。在本文中,您将了解RBAC的工作原理、最小权限原则的含义和目的,以及如何在实践中使用 MongoDB 的访问权限功能。

访问控制(也称为授权)是一种安全技术,涉及确定谁可以访问哪些资源。

为了更好地理解 MongoDB 中的访问控制,首先将其与另一个不同但密切相关的概念进行区分:身份验证。身份验证是确认用户或客户端是否确实是他们声称的身份的过程。另一方面,授权涉及为给定用户或用户组设置规则,以定义他们可以执行哪些操作以及他们可以访问哪些资源。

MongoDB 中的身份验证

在许多数据库管理系统中,用户仅通过用户名和密码对进行识别。当使用有效凭据连接到数据库时,用户将经过身份验证并被授予与该用户关联的访问级别。在这种方法中,用户目录是扁平的,这意味着对于整个数据库服务器,每个用户名必须是唯一的。

相比之下,MongoDB 采用更复杂的用户目录结构。在 MongoDB 中,用户不仅可以通过用户名来识别,还可以通过创建用户的数据库来识别。对于每个用户,创建他们的数据库称为该用户的身份验证数据库。

这意味着在 MongoDB 中,可以有多个用户具有相同的用户名(例如sammy),只要它们是在不同的身份验证数据库中创建的。要以用户身份进行身份验证,您不仅必须提供用户名和密码,还必须提供与该用户关联的身份验证数据库的名称。

人们可能会假设在给定身份验证数据库中创建的用户将具有仅对该特定数据库可用的访问权限,但事实并非如此。每个用户,无论是在哪个身份验证数据库中创建的,都可以具有跨不同数据库分配的权限。

MongoDB 中的授权(基于角色的访问控制)

在 MongoDB 中,您可以通过称为基于角色的访问控制(通常缩写为RBAC)的机制来控制谁有权访问数据库上的哪些资源以及访问的程度。

在基于角色的访问控制中,用户无权直接对资源执行操作,例如将新文档插入数据库或查询特定集合。这将使安全策略难以管理并与系统中的许多用户保持一致。相反,允许对特定资源执行操作的规则被分配给角色。

将角色视为给定用户的工作或职责之一可能会有所帮助。例如,经理可能对公司 MongoDB 实例中的每个文档具有读写访问权限,而销售分析师可能仅对销售记录具有只读访问权限。

角色是用一组一个或多个权限来定义的。每个权限都包含一个操作(例如创建新文档、从文档检索数据或创建和删除用户)以及可以执行该操作的资源(例如名为 的数据库或名为 的集合reports)orders。就像在现实生活中一样,一家公司可能有许多销售分析师和员工,他们承担多个职责,在 MongoDB 中,许多用户可以分配给同一角色,并且单个用户可以被授予多个角色。

角色通过角色名称和数据库的组合来标识,因为每个角色(在数据库中创建的角色除外admin)只能包含应用于其自己数据库的权限。通过向用户授予在其身份验证数据库之外的数据库中定义的角色,可以向用户授予对多个数据库进行操作的权限。可以在创建用户时或此后的任何时间授予角色。还可以随意撤销角色成员资格,从而可以轻松地将用户管理与访问权限管理分离。

MongoDB 提供了一组内置角色,描述数据库系统中常用的权限,例如read授予只读访问权限、readWrite授予读写权限或dbOwner授予对给定数据库的完全管理权限。对于更具体的场景,还可以使用自定义权限集创建用户定义的角色。

基于角色的访问控制可以为用户分配执行各自任务所需的最低、精确级别的访问权限。这是一种重要的安全实践,称为最小特权原则。

  • 绑定IP地址

mongod 参数:–bind_ip << ip address >>

默认值是所有的IP地址都能访问,该参数指定MongoDB对外提供服务的绑定IP地址,用于监听客户端Application的连接,客户端只能使用绑定的IP地址才能访问mongod,其他IP地址是无法访问的。

  • 设置监听端口

mongod 参数:–port

MongoDB默认监听的端口是27017,该参数显式指定MongoDB实例监听的TCP端口,只有当客户端Application连接的端口和MongoDB实例监听的端口一致时,才能连接到MongoDB实例。

  • 启用用户验证

mongod 参数:–auth

默认值是不需要验证,即 –noauth,该参数启用用户访问权限控制;当mongod使用该参数启动时,MongoDB会验证客户端连接的账户和密码,以确定其是否有访问的权限。如果认证不通过,那么客户端不能访问MongoDB的数据库。

  • 权限认证

mongo 参数:-u << username >> -p << password >>
mongo 参数:–authenticationDatabase 指定创建User的数据库;在特定的数据库中创建User,该DB就是User的authentication database。

在连接mongo时,使用参数 –authenticationDatabase,会认证 -u 和 -p 参数指定的账户和密码。如果没有指定验证数据库,mongo使用连接字符串中指定的DB作为验证数据块。

准备环境

[root@MongoDB-Server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
[root@MongoDB-Server ~]# uname -r
3.10.0-1160.el7.x86_64

[root@MongoDB-Server ~]# setenforce 0
[root@MongoDB-Server ~]# sed -i.bak '7s/enforcing/disabled/' /etc/selinux/config

[root@MongoDB-Server ~]# systemctl stop firewalld
[root@MongoDB-Server ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[root@MongoDB-Server ~]# firewall-cmd --state
not running

安装 MongoDB 6.0

  • 前文《MongoDB 基础知识梳理》已使用过yum源安装,则本文使用二进制安装包。

    下载 MongoDB, Mongosh

    [root@MongoDB-Server ~]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.11.tgz [root@MongoDB-Server ~]# wget https://downloads.mongodb.com/compass/mongosh-2.0.2-linux-x64.tgz

    解压缩

    [root@MongoDB-Server ~]# mkdir /data/apps/ -p [root@MongoDB-Server ~]# tar -xf mongodb-linux-x86_64-rhel70-6.0.11.tgz -C /data/apps/ [root@MongoDB-Server ~]# tar -xf mongosh-2.0.2-linux-x64.tgz -C /data/apps/

    重命名目录

    [root@MongoDB-Server ~]# cd /data/apps/ [root@MongoDB-Server apps]# ls mongodb-linux-x86_64-rhel70-6.0.11 mongosh-2.0.2-linux-x64 [root@MongoDB-Server apps]# mv mongodb-linux-x86_64-rhel70-6.0.11 mongodb [root@MongoDB-Server apps]# mv mongosh-2.0.2-linux-x64 mongosh [root@MongoDB-Server apps]# ls mongodb mongosh

    环境变量

    [root@MongoDB-Server ~]# ln -s /data/apps/mongodb/bin/* /usr/local/bin/ [root@MongoDB-Server ~]# ln -s /data/apps/mongosh/bin/* /usr/local/bin/

    [root@MongoDB-Server ~]# ls -l /usr/local/bin/ lrwxrwxrwx 1 root root 38 Nov 1 11:49 install_compass -> /data/apps/mongodb/bin/install_compass lrwxrwxrwx 1 root root 29 Nov 1 11:49 mongod -> /data/apps/mongodb/bin/mongod lrwxrwxrwx 1 root root 29 Nov 1 11:49 mongos -> /data/apps/mongodb/bin/mongos lrwxrwxrwx 1 root root 30 Nov 1 11:49 mongosh -> /data/apps/mongosh/bin/mongosh lrwxrwxrwx 1 root root 42 Nov 1 11:49 mongosh_crypt_v1.so -> /data/apps/mongosh/bin/mongosh_crypt_v1.so

    创建Mongod相关目录

    [root@MongoDB-Server ~]# useradd -r -M /var/lib/mongo -s /bin/false [root@MongoDB-Server ~]# install -d /var/lib/mongo /var/log/mongodb -o mongod -g mongod

    [root@MongoDB-Server ~]# ls -dl /var/lib/mongo /var/log/mongodb drwxr-xr-x 2 mongod mongod 6 Nov 1 12:22 /var/lib/mongo drwxr-xr-x 2 mongod mongod 6 Nov 1 12:22 /var/log/mongodb

    使用mongod用户启动/停止mongod服务(命令行方式)

    [root@MongoDB-Server ~]# su mongod -s /bin/bash -c “mongod -fork -dbpath /var/lib/mongo/ -logpath /var/log/mongodb/mongod.log -logappend” [root@MongoDB-Server ~]# su mongod -s /bin/bash -c “mongod -fork -dbpath /var/lib/mongo/ -logpath /var/log/mongodb/mongod.log -logappend –shutdown”

登录Mongodb,创建用户

[root@MongoDB-Server ~]# mongosh
test> show dbs
admin   40.00 KiB
config  60.00 KiB
local   72.00 KiB

test> use admin
switched to db admin

admin> show collections
system.version

# 创建root用户
admin> db.createUser({user:"root", pwd:"root@123", roles:[{role:"root", db:"admin"}]})

# 创建admin用户
> db.createUser({
      user: "myAdmin",
      pwd: passwordPrompt(), // or cleartext password
      roles: [
        { role: "userAdminAnyDatabase", db: "admin" },
        { role: "readWriteAnyDatabase", db: "admin" }
      ]
    })

开启认证方式

# 方式一:启动时配置--auth参数开启
[root@MongoDB-Server ~]# su mongod -s /bin/bash -c "mongod -fork -dbpath /var/lib/mongo/ -logpath /var/log/mongodb/mongod.log -logappend --auth"

# 方式二:配置文件中开启
[root@MongoDB-Server ~]# cat /etc/mongod.conf
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

# 如果你没有可用的用户,请勿配置该参数
security:
    authorization: enabled

# 使用mongod用户启动/停止mongod服务(配置文件方式)
[root@MongoDB-Server ~]# su mongod -s /bin/bash -c "nohup mongod -f /etc/mongod.conf &> /dev/null &"
[root@MongoDB-Server ~]# su mongod -s /bin/bash -c "mongod -f /etc/mongod.conf --shutdown &> /dev/null"

# 验证用户账号及其密码
[root@MongoDB-Server ~]# mongosh
test> use admin      # 切换至admin库
switched to db admin

admin> show dbs    # 提示需身份验证
MongoServerError: command listDatabases requires authentication
admin> db.system.users.find()
MongoServerError: command find requires authentication

admin> db.auth("root","root@123")
{ ok: 1 }    # 认证成功

admin> show dbs
admin   180.00 KiB
config   72.00 KiB
local    72.00 KiB

# 连接时进行身份验证
[root@MongoDB-Server ~]# mongosh --port 27017  --authenticationDatabase "admin" -u "myAdmin" -p

# 连接后进行身份验证
[root@MongoDB-Server ~]# mongosh --port 27017
> use admin
admin> db.auth("myAdmin", passwordPrompt()) // or cleartext password

MongoDB Roles(内置角色)

  • 数据库用户角色:read、readWrite;
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin;
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
  • 备份恢复角色:backup、restore;
  • 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
  • 超级用户角色:root
  • 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
  • 内部角色:__system

具体角色

  • Read:允许用户读取指定数据库
  • readWrite:允许用户读写指定数据库
  • dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
  • userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
  • clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
  • readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
  • readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
  • userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
  • dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
  • root:只在admin数据库中可用。超级账号,超级权限

用户管理

# 查询单用户
db.getUser("myUser")
db.system.users.find({user:"myUser"})

# 查询所有用户
show users
db.getUsers()
db.system.users.find()

# 身份验证
db.auth( <myUser>, passwordPrompt() )    # 提示输入密码
db.auth( <myUser>, <myUserpasswd> )          # 明文密码
# 返回:1为身份验证成功

# 创建新用户,授权myAdmin用户所有数据库的读写及创建、删除和管理用户的权限
use admin
db.createUser(
   {
     user: "myAdmin",
     pwd: passwordPrompt(),  // Or  "<cleartext password>"
    roles: [
      { role: "userAdminAnyDatabase", db: "admin" },
      { role: "readWriteAnyDatabase", db: "admin" }
   }
)

# 普通用户,授权myUser用户对myDBName的读写操作,该用户只能从192.0.2.0段连接到198.51.100.0段
use admin
  db.createUser(
     {
       user: "myUser",
       pwd: passwordPrompt(),      // Or  "<cleartext password>"
       roles: [ { role: "readWrite", db: "myDBName" } ],
       authenticationRestrictions: [ {
          clientSource: ["192.0.2.0"],
          serverAddress: ["198.51.100.0"]
       } ]
     }
  )

# 修改用户密码
use admin
db.changeUserPassword("myUser", passwordPrompt())
db.changeUserPassword("myUser", "myUserpasswd")

db.updateUser("myUser", {pwd:"myUserpasswd"})

# 删除单个用户
use admin
db.dropUser("myUser")
db.system.users.remove({user:"myUser"})
db.removeUser()    // 旧版本,已弃用

# 删除所有用户
db.dropAllUsers()     
db.system.users.remove({})

角色管理

# 授权myUser用户对myDBName数据库的读写操作
db.grantRolesToUser("myUser", [{role: "readWrite", db: "myDBName"}])

# 撤销myUser用户对myDBName数据库的读写操作
db.revokeRolesFromUser("myUser", [{role: "readWrite", db: "myDBName"}])

# 修改myUser用户仅对myDBName数据库只读操作
db.updateUser("myUser", {roles: [ {role: "read", db: "myDBName"} ]})
内容
  • Unity 中的存档系统(本地存档)
    Unity 中的存档系统(本地存
    2023-12-09
    思想.在游戏过程中,玩家的背包、登录、人物系统都与数据息息相关,无论是一开始就设定好的默认数据,还是可以动态存取的数据,
  • Mybatis的工作原理
    Mybatis的工作原理
    2023-12-05
    mybatis的工作原理.mybatis基本工作原理.封装sql ->调用JDBC操作数据库 -> 返回数据封装.JDB
  • 数据分析师如何用SQL解决业务问题?
    数据分析师如何用SQL解决业务问
    2023-12-03
    本文来自问答。.提问:数据分析人员需要掌握sql到什么程度?.请问做一名数据分析人员,在sql方面需要掌握到什么程度呢?
  • 缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找
    缓存面试解析:穿透、击穿、雪崩,
    2023-12-03
    为什么使用缓存.在程序内部使用缓存,比如使用map等数据结构作为内部缓存,可以快速获取对象。通过将经常使用的数据存储在缓
  • 驱动开发:内核封装WFP防火墙入门
    驱动开发:内核封装WFP防火墙入
    2023-12-02
    WFP框架是微软推出来替代TDIHOOK传输层驱动接口网络通信的方案,其默认被设计为分层结构,该框架分别提供了用户态与内
  • Unity学习笔记--数据持久化Json
    Unity学习笔记--数据持久化
    2023-12-02
    JSON相关.json是国际通用语言,可以跨平台(游戏,软件,网页,不同OS)使用,.json语法较为简单,使用更广泛。
  • 如何用 30s 给面试官讲清楚什么是 Token?
    如何用 30s 给面试官讲清楚什
    2023-12-01
    引言.前文介绍了 Session-Cookie 的认证过程,简单回顾下基本步骤:.客户端(浏览器)向服务器发送用户名和密
  • 可爱儿童内衣套装,优质棉质,柔软透气,呵护宝宝肌肤
    可爱儿童内衣套装,优质棉质,柔软
    2024-01-05
    可爱儿童内衣套装,优质棉质,柔软透气,呵护宝宝肌肤.宝宝的皮肤是非常娇嫩的,所以选择合适的内衣套装对于宝宝的健康和舒适至
  • 时尚潮流运动鞋
    时尚潮流运动鞋
    2024-01-15
    时尚潮流运动鞋.时尚潮流运动鞋一直是年轻人喜爱的时尚单品,它不仅舒适耐穿,更是一种个性的象征。随着时尚潮流不断更新,运动
  • 修身弹力牛仔裤
    修身弹力牛仔裤
    2023-12-26
    修身弹力牛仔裤:展现你的魅力.一、时尚的必备单品.修身弹力牛仔裤一直都是时尚界的必备单品,它不仅可以展现出个人的魅力,还
  • 休闲简约短袖衬衫
    休闲简约短袖衬衫
    2023-12-21
    休闲简约短袖衬衫.现代人生活节奏快,休闲简约的穿着成为时尚潮流。短袖衬衫作为经典的休闲单品,一直备受时尚人士的青睐。它舒
  • 休闲宽松T恤衫,释放自在舒适气息
    休闲宽松T恤衫,释放自在舒适气息
    2023-12-26
    休闲宽松T恤衫,释放自在舒适气息.在这个喧嚣的都市中,人们的生活节奏变得越来越快,压力也越来越大。因此,人们更加注重舒适
  • 潮流风衣大衣,彰显都市时尚风采
    潮流风衣大衣,彰显都市时尚风采
    2023-12-16
    潮流风衣大衣,彰显都市时尚风采.潮流风衣大衣一直是时尚界备受追捧的单品之一。它既能为我们遮风挡雨,又能为我们穿出时尚感,
  • 时尚修身连衣裙,展现优雅女性魅力
    时尚修身连衣裙,展现优雅女性魅力
    2023-12-06
    时尚修身连衣裙,展现优雅女性魅力.时尚修身连衣裙一直是女性衣橱里的必备单品,不仅款式多样,而且能够展现出女性的优雅魅力。
  • 保暖舒适羊毛大衣
    保暖舒适羊毛大衣
    2024-01-05
    保暖舒适羊毛大衣.冬季来临,寒冷的天气让人们更加注重保暖。在这个时候,一件保暖舒适的羊毛大衣成为了许多人的首选。羊毛大衣
  • 萌娃配饰套装,包包、帽子、围巾等,增添宝宝的时尚气息
    萌娃配饰套装,包包、帽子、围巾等
    2024-01-20
    萌娃配饰套装,为宝宝增添时尚气息.宝宝是家庭的小太阳,****们都希望给他们最好的一切。随着时尚的发展,宝宝的时尚潮流也
  • 轻盈雪纺衬衫,打造清新淑女形象
    轻盈雪纺衬衫,打造清新淑女形象
    2023-12-31
    轻盈雪纺衬衫,打造清新淑女形象.雪纺材质的衬衫一直以来都是清新淑女形象的代表,它轻盈飘逸的质地,柔软透气的触感,让人仿佛