mongodb多业务线隔离必须通过数据库级权限实现,每个业务线专属数据库配最小权限角色,禁用内置角色、显式限定资源范围、用户在admin库创建并加ip限制,最后验证越权操作被拒绝。

MongoDB 多业务线用户隔离必须靠数据库级权限,不是靠应用层分库
业务线之间不能共享数据,光靠应用连接不同 database 不够——用户如果拥有 root 或 dbOwner 权限,就能跨库执行 listDatabases、甚至用 copyDatabase(旧版)或聚合管道读取其他库的集合。真正的隔离起点是:每个业务线只分配一个专属数据库 + 仅对该库有最小必要权限的角色。
用 createRole 定义业务专属角色,别直接授内置角色
直接给用户加 readWrite 或 dbAdmin 是最常见错误,这类角色默认作用域是“当前认证库”,但用户若以 admin 库认证,就能对任意库执行操作。必须显式限定作用域:
- 先在
admin库中运行createRole,roles字段里每个权限项都带db和collection明确指定范围 - 例如为“订单线”建角色:
db.runCommand({createRole:"order_rw",privileges:[{resource:{db:"order_db",collection:""},actions:["find","insert","update","delete"]}],roles:[]}) - 避免使用通配符
collection:""以外的模糊匹配;若只需操作orders表,就写死collection:"orders" - 不继承任何内置角色(
roles:[]),防止隐式获得跨库能力
用户必须在 admin 库创建,且 authenticationRestrictions 锁定 IP 和数据库
用户不在 admin 库建,就无法被赋予自定义角色;而没加访问限制,等于白设角色:
- 创建用户时,
db.createUser的roles字段引用上一步建的专属角色,如{role:"order_rw",db:"admin"} - 务必加上
authenticationRestrictions,例如只允许从订单服务所在网段连:{clientSourceIP:"10.20.30.0/24",serverAddress:["mongodb-prod-01:27017"]} -
authenticationRestrictions中的clientSourceIP必须精确到子网,别写0.0.0.0/0;MongoDB 不校验该 IP 是否真实可达,只做连接时比对 - 用户认证库固定为
admin,但权限生效库由角色定义决定——这点容易混淆,记清楚:角色在哪定义,权限就在哪生效
验证隔离是否生效:用 mongosh 模拟越权操作
配置完别信文档,立刻用实际命令测试边界:
- 用新用户登录:
mongosh "mongodb://order_user:pwd@host:27017/admin?authMechanism=SCRAM-SHA-256" - 执行
db.getSiblingDB("user_db").users.find().limit(1)—— 应报错not authorized on user_db to execute command { find: ... } - 执行
db.adminCommand({listDatabases:1})—— 应报错not authorized on admin to execute command { listDatabases: 1 } - 检查当前权限:
db.runCommand({connectionStatus:1}).authInfo.authenticatedUserRoles,确认只列出你分配的那个角色,且db字段是"admin"(角色归属库),不是业务库名
最容易被忽略的是:角色定义里的 resource 路径和用户实际连接时的认证库、目标库三者关系。写错一个 db 字符串,隔离就形同虚设。










