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