当前位置: 首页 > news >正文

Java-164 MongoDB 认证与权限实战:单实例与分片集群 整体认证配置实战 最小化授权/错误速查/回滚剧本

TL;DR

  • 场景:把 MongoDB 从“裸奔”切到最小权限,覆盖单实例 + 分片集群的认证与授权落地。
  • 结论:正确顺序=本机创建 root@admin → 开启 authorization → 按库分权(read/readWrite/dbOwner);分片用 KeyFile 做组件间认证,在 mongos 上统一建用户。10 分钟跑通,提供可回滚路径。
  • 产出:MRE 脚本、mongodb.conf 模板、角色授予清单、报错速查卡、回滚剧本;适配 MongoDB 7.0/8.0,示例使用 mongosh + URI(含 ?authSource)。

Java-164 MongoDB 认证与权限实战:单实例与分片集群 整体认证配置实战 最小化授权/错误速查/回滚剧本

认证流程

创建 wzk_test1 数据库并创建了两个用户,zhangsan用户拥有读写权限,lisi用户拥有只读权限,测试这两个账户的权限。
这里需要以管理员登录测试权限。

创建管理员

MongoDB 安全认证机制详解

管理员账号的必要性

在开启 MongoDB 安全检查前,必须先在 admin 数据库中创建至少一个管理员账号。admin 数据库中的用户拥有特殊权限,能够执行管理操作和访问所有数据库。这些用户被视为全局管理员,对整个 MongoDB 实例拥有最高权限。

身份验证机制的工作原理

MongoDB 的身份验证机制遵循以下原则:

  1. admin 数据库优先:当启用身份验证时,MongoDB 首先会检查 admin 数据库中是否存在用户账号
  2. 权限继承机制:如果 admin 数据库为空,即使其他数据库(如 test、production)中存在用户账号,身份验证也不会完全生效
  3. 超级权限漏洞:当 admin 数据库为空时,客户端可以不提供任何认证信息就能获得完全的读写权限,这会使安全检查形同虚设

安全配置的正确步骤

为确保安全认证有效,应按以下顺序操作:

  1. 首先在 admin 数据库创建管理员账号:
use admin
db.createUser({user: "adminUser",pwd: "securePassword",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]}
)
  1. 重启 MongoDB 服务并启用身份验证:
mongod --auth
  1. 连接时必须提供认证信息:
mongo -u adminUser -p securePassword --authenticationDatabase admin

实际应用场景示例

在企业环境中,通常会配置:

  • 1-2 个具有 userAdminAnyDatabase 角色的超级管理员账号
  • 针对具体应用创建专门的数据库用户,限制其权限范围
  • 定期轮换密码和检查权限分配

这种分层安全架构既能保证管理需要,又能遵循最小权限原则。

创建普通用户

如下所示 wzk_test1 是自己新建的新建库,没安全认证之前可以随意 CRUD,其余的都是 MongoDB 自带的数据库。

查看数据库内容

为 admin 库创建管理员之后,现在来为普通数据库创建普通用户,以 mydb1 为例,方式与创建管理员一致,切换到指定数据库进行创建即可。

为 wzk_test1 数据库创建了两个用户,zhangsan 拥有读写权限,lisi 拥有只读权限,密码123456

use wzk_test1db.createUser({user:"zhangsan",pwd:"123456",roles:[{role:"readWrite",db:"wzk_test1"}]
})db.createUser({user:"lisi",pwd:"123456",roles:[{role:"read",db:"wzk_test1"}]
})

创建新的用户

接着从客户端关闭 MongoDB 服务端,之后服务端会以安全认证方式启动。

use admin
db.shutdownServer()

也可以重新后台上杀掉服务再重启也OK的。
别忘了启动的时候,配置里边的 auth 是 true

dbpath=/data/db/
port=27000
bind_ip=0.0.0.0
fork=true
logpath = /data/db/MongoDB.log
logappend = true
auth=true

启动服务:

./mongod -f mongodb.conf

验证权限

普通用户现在仍然可以像之前一样通过命令行客户端连接到 MongoDB 数据库实例,例如使用以下命令直接登录到 wzk_test1 数据库:

mongo 127.0.0.1:27017/wzk_test1 -u username -p password

虽然登录过程本身是成功的(系统不会拒绝连接),但在登录后用户会立即遇到诸多操作限制。具体表现为:

  1. 系统日志输出明显减少,不再显示完整的操作日志信息
  2. 尝试执行基础查询命令时会遇到权限不足的错误:
    • show dbs 命令失败 - 无法查看数据库列表
    • show tables 命令失败 - 无法查看集合列表
    • 即使访问那些不需要安全认证的数据库也会操作失败

这种限制的根本原因是 MongoDB 的访问控制机制在起作用。系统会严格遵循"最小权限原则",每个用户只能在自己的权限范围内进行操作。

正确的操作流程应该是:

  1. 先建立数据库连接
  2. 然后立即执行授权认证:
db.auth("username", "password")
  1. 只有认证通过后,才能执行权限范围内的操作

例如,一个只有wzk_test1数据库读写权限的用户:

  • 可以正常查询wzk_test1中的集合数据
  • 可以创建/删除该库中的集合
  • 但无法查看其他数据库信息
  • 也不能执行任何数据库管理命令

这种设计确保了数据库的安全性,防止了权限越界操作。在实际应用中,DBA需要根据业务需求,通过db.grantRolesToUser()等方法精确地为每个用户配置适当的权限范围。

分片集群认证

PS:开启安全认证之前,进入路由创建管理员和普通用户

关闭所有配置

这里需要关闭所有的配置节点、分片节点、路由节点

killall mongod

生成秘钥

生成一个秘钥文件,并修改权限

openssl rand -base64 756 > testKeyFile.file
chmod 600 testKeyFile.file

生成新的key文件

配置秘钥

配置节点集群和分片节点集群,开启认证和指定秘钥文件:

auth=true
keyFile=testKeyFile.file

在路由配置文件中,设置秘钥文件:

keyFile=testKeyFile.file

启动服务

启动所有配置节点、分片节点、路由节点,使用路由进行权限验证。

./mongod -f config/config-17017.conf
./mongod -f config/config-17018.conf
./mongod -f config/config-17019.conf
./mongod -f shard/shard1/shard1-37017.conf
./mongod -f shard/shard1/shard1-37018.conf
./mongod -f shard/shard1/shard1-37019.conf
./mongod -f shard/shard2/shard2-47017.conf
./mongod -f shard/shard2/shard2-47018.conf
./mongod -f shard/shard2/shard2-47019.conf
./mongos -f route/route-27017.conf

最小化可运行

准备配置

mongodb.conf(最小模板):

storage:dbPath: /data/db
systemLog:destination: filepath: /data/db/mongodb.loglogAppend: true
net:bindIp: 0.0.0.0port: 27017
processManagement:fork: true
# 第一次先不要开启 authorization,创建好用户再启用
# security:
#   authorization: enabled

启动:

mongod -f mongodb.conf

创建首个管理员(admin 库)

通过 mongosh 连接本机(触发 localhost 例外,仅用于创建首个用户)。

// 连接
mongosh --host 127.0.0.1 --port 27017use admindb.createUser({user: 'adminUser',pwd:  '强密码_建议16+位',roles: [ { role: 'root', db: 'admin' } ]
})

说明:相较 userAdminAnyDatabase,root 更贴合超管需求;若公司有分权要求,可拆分多个管理员角色。

启用授权并重启

编辑 mongodb.conf:

security:authorization: enabled

重启:

mongod --shutdown --config mongodb.conf || true
mongod -f mongodb.conf

创建业务库与用户

mongosh -u adminUser -p '强密码_建议16+位' --authenticationDatabase admin \--host 127.0.0.1 --port 27017use wzk_test1db.createUser({user: 'zhangsan',pwd:  '建议强密码',roles: [ { role: 'readWrite', db: 'wzk_test1' } ]
})db.createUser({user: 'lisi',pwd:  '建议强密码',roles: [ { role: 'read', db: 'wzk_test1' } ]
})

权限验证

只读用户 lisi:

mongosh 'mongodb://lisi:密码@127.0.0.1:27017/wzk_test1?authSource=wzk_test1'
// 允许:查询
use wzk_test1db.collection('demo').findOne()// 拒绝:写入(返回 Unauthorized error 13)
db.collection('demo').insertOne({a:1})

读写用户 zhangsan:

mongosh 'mongodb://zhangsan:密码@127.0.0.1:27017/wzk_test1?authSource=wzk_test1'
// 允许:写入/查询
use wzk_test1db.collection('demo').insertOne({a:1})db.collection('demo').find({a:1})// 默认不能查看“其他数据库列表”
show dbs  // 需要 listDatabases 权限

最小化授权

管理员分权

  • 平台管理员:root(仅少量人员掌握)。
  • DB 管理员:dbAdminAnyDatabase + userAdminAnyDatabase。
  • 集群管理员:clusterAdmin(分片/复制集管理)。

应用分权

  • 读写:readWrite@
  • 只读:read@
  • DDL/索引:dbOwner@ 或自定义角色(尽量别给 readWriteAnyDatabase)。

密码轮换

  • 新建临时用户 → 应用切换凭据 → 删除旧用户(或更新 pwd 并同步配置管理/密钥库)。

审计要点

开启 auditLog(企业版)或至少保留 systemLog;对高危操作(增删角色、授予 root)保留变更记录。

错误速查

现象/报错可能原因核验命令解决动作
Authentication failed / SCRAM用户/密码错;authSource 错db.runCommand({connectionStatus:1,showPrivileges:true})用 URI 指定 ?authSource=<db>;核对用户是否建在 wzk_test1/admin
not authorized on <db> to execute角色权限不足db.getUser('<user>')补授所需动作(如 readWrite/dbOwner
listDatabases 被拒未授 listDatabasesdb.adminCommand({listDatabases:1})管理/只读账号按需授 readAnyDatabase(谨慎)
Failed to set up listener: key file permissionsKeyFile 权限不安全ls -l /path/keyfilechown mongod:mongod keyfile && chmod 600 keyfile
开启 authorization 后所有客户端都失败先启用了授权但尚无 admin 用户-按“localhost 例外”在本机创建首个 admin(或临时停授权,见回滚)
user is not allowed to do action dropDatabase角色不含 DDLdb.getUser()使用 dbOwner 或授予对应 actions 的自定义角色

回滚剧本

仅用于救援,执行前隔离网络或绑定 127.0.0.1,避免暴露无授权实例。

单实例:

  • 停服:mongod --shutdown --config mongodb.conf

  • 临时以无授权方式、仅绑定本机启动:
    mongod --port 27017 --bind_ip 127.0.0.1 --dbpath /data/db --fork
    –logpath /data/db/mongodb-rollback.log --logappend

  • 连接本机,修复用户/角色:创建/重置 adminUser 密码或增授权限。

  • 正常关闭后,按启用授权的配置重启。

分片集群:

  • 优先通过 mongos 使用 clusterAdmin/root 账号修复;避免逐节点关授权。
  • 如必须降级,先全员绑定 127.0.0.1,并在维护窗口逐步处理(顺序:configsvr→shard→mongos),修复后恢复授权。

其他系列

🚀 AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈
🔗 AI模块直达链接

💻 Java篇持续更新中(长期更新)

Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
🔗 大数据模块直达链接

http://www.dtcms.com/a/553091.html

相关文章:

  • 北京公司的网站建设きょこんきょうしゃ在线
  • 第4讲:理解Flutter的灵魂 - “Everything is a Widget”
  • 驱动精灵、驱动人生、NVIDIA专业显卡驱动、360驱动大师、联想乐驱动,电脑驱动修复工具大全
  • Spring Boot 4与Spring Framework 7:云原生Java的全新革命与企业级实战
  • 虚拟机在云原生与智能时代的未来应用场景探析
  • 电脑如何设置wifi密码,详细步骤教程指南
  • C#面试题及详细答案120道(51-60)-- LINQ与Lambda
  • 北京网站备案的地址ps怎么做网站分隔线
  • DLSS是什么
  • web网页开发,旧版在线%考试,判题%系统demo,基于python+flask+随机分配考试题目,基于开发语言python,数据库mysql
  • 【C++】哈希表封装实现 unordered_map 和 unordered_set
  • 353-Spring AI Alibaba ARK 多模型示例
  • 安徽海绵城市建设协会网站ip查询网站备案查询系统
  • MVVM架构与ICommand核心笔记
  • Web后端开发学习总结
  • 萍乡做网站的公司有哪些门户网站建设方案ppt 百度文库
  • Wireshark抓包教程:获取网站登录凭证
  • 销售驱动的黄昏:医药商业化模式的效率悖论与转型必然
  • 【mysql】锁机制 - 2.行锁间隙锁临键锁
  • 做网站制作需要多少钱网络设计公司有哪些
  • 外卖骑手的Python转型指南:从送餐到编程的实战路径
  • 一款端侧TTS:NeuTTS-Air,3秒语音克隆,声音听起来没有生硬感,语气和节奏感相对自然
  • 网站建设网站软件页面设计属于什么知识产权
  • 网站管理的含义长春做网站哪家好
  • Nacos和Nginx集群,项目启动失败问题
  • Opencv(五): 腐蚀和膨胀
  • 17.React获取DOM的方式
  • 编码器读写操作方式
  • WEB服务
  • 2025年10月31日 AI大事件