MongoDB用户权限配置疑问:单文档访问与角色授权报错
嘿,我来帮你理清楚这些MongoDB的问题,一步步拆解:
一、先搞懂MongoDB里各个数据库的作用
- admin库:这是MongoDB的「系统管理专属库」,所有超级管理员账号、全局权限角色都存在这里,用来处理集群/实例级的管理操作,绝对不要用来存业务用户数据。
- 自定义数据库:比如你提到的
custom或testdb,这才是存放业务数据(客户端用户、专属文档)的正确地方,完全根据你的业务需求创建和命名。 - local库:这个库的数据不会同步到副本集的其他节点,只存在于当前实例,一般用来存本地实例的专属状态数据(比如副本集节点信息),和业务无关。
- config库:仅在分片集群环境下有用,用来存储分片的配置信息,单实例或普通副本集场景下基本用不上。
结论:你的客户端用户和对应专属文档,都应该存在自定义数据库里,admin库只用来管理超级管理员账号。
二、实现用户仅访问自己的专属文档
你需要的是文档级别的权限隔离,MongoDB可以通过「自定义角色+文档过滤条件」来实现。先说说你之前遇到的授权错误问题:
你创建角色后执行
show collections报错:2018-05-13T20:38:09.463+0300 E QUERY [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not authorized on testdb to execute command { listCollections: 1.0, filter: {}, $db: \"testdb\" }", "code" : 13, "codeName" : "Unauthorized" }
这个错误原因很明确:你创建的User角色没有**listCollections**权限,而show collections本质是调用listCollections命令,所以被拒绝了。另外,要实现文档级隔离,你还需要给角色添加「带文档过滤规则的操作权限」。
正确的实现步骤:
1. 切换到自定义数据库
先创建并进入你的业务数据库:
use testdb
2. 创建带文档过滤的自定义角色
这里要注意两点:
- 加上
listCollections权限,让用户能看到集合(如果不需要在工具里看集合列表也可以不加,但Studio 3T要显示集合必须有这个权限) - 针对
ClientCollection添加带过滤条件的操作权限,假设你的文档里有一个owner字段(值对应用户名,比如ClientUser1),这样用户只能访问自己的文档。
db.createRole({ role: "ClientUserRole", privileges: [ // 允许查看当前库的集合列表 { resource: { db: "testdb", collection: "" }, actions: ["listCollections"] }, // 仅允许访问当前用户拥有的文档,用$expr匹配文档的owner字段和当前用户名 { resource: { db: "testdb", collection: "ClientCollection" }, actions: ["find", "update", "insert", "remove"], filter: { $expr: { $eq: ["$owner", "$$USER"] } } } ], roles: [] })
3. 创建客户端用户并绑定角色
给每个客户端用户创建账号,只赋予上面的ClientUserRole角色,确保权限最小化:
// 创建ClientUser1 db.createUser({ user: "ClientUser1", pwd: "1234", roles: [{ role: "ClientUserRole", db: "testdb" }] }) // 创建ClientUser2 db.createUser({ user: "ClientUser2", pwd: "1234", roles: [{ role: "ClientUserRole", db: "testdb" }] })
4. 验证权限效果
用ClientUser1连接后:
- 执行
show collections可以看到ClientCollection - 执行
db.ClientCollection.find()只会返回owner为ClientUser1的文档(也就是你的Document1ForUser1Only) - 尝试修改其他用户的文档会直接提示未授权
三、WPF客户端连接注意事项
你的连接字符串格式没问题,注意指定正确的数据库(就是你创建用户的testdb):
new MongoClient("mongodb://ClientUser1:1234@127.0.0.1:27017/testdb")
这样连接后,客户端只能访问自己的专属文档,完全看不到或修改不了其他用户的数据。
内容的提问来源于stack exchange,提问作者Dzmitry Dym
相关产品推荐
相关产品推荐

