MongoDB自定义角色实现用户仅读取自身详情条目可行性咨询
问题
我希望创建一个存储MongoDB用户详情的数据库,除管理员外,每个MongoDB用户仅能读取集合中分配给自己的用户详情条目——该角色下的所有用户仅可读取entryOwner字段值等于其userId的数据条目。请问能否通过单一自定义用户角色实现该需求,还是只能采用为每个用户创建仅其可访问的单条目集合这种低效方案?
我调研该方案的可行性是为了实现MongoDB的三类用途:
- 替代LDAP服务器,在共享同一数据库的不同应用间实现更安全的认证;
- 存储不同应用的配置信息,这些配置字段结构一致,但仅对应应用的用户可访问;
- 通过单MongoDB实例管理多个独立应用与项目的数据库。
回答
完全可以通过单一自定义角色实现需求,无需为每个用户创建独立集合,这是更高效且符合MongoDB权限设计的方案。
实现步骤
- 创建带过滤条件的自定义角色
MongoDB支持在角色权限中指定filter参数,结合内置变量$$USER_ID(当前认证用户的ID),可以限制角色仅能读取entryOwner字段与自身ID匹配的文档。
执行以下命令创建自定义角色(替换yourDB和userDetails为你的数据库名和集合名):
db.createRole({ role: "selfEntryReader", privileges: [ { resource: { db: "yourDB", collection: "userDetails" }, actions: ["find"], filter: { entryOwner: { $eq: "$$USER_ID" } } } ], roles: [] })
- 为普通用户分配该角色
创建或更新用户时,将上述自定义角色分配给他们,管理员则使用MongoDB内置的高权限角色(如root、dbAdmin)即可:
// 创建普通用户 db.createUser({ user: "appUser1", pwd: "yourPassword", roles: [{ role: "selfEntryReader", db: "yourDB" }] })
- 验证权限效果
切换到普通用户身份执行查询:
db.userDetails.find()
此时只会返回entryOwner字段值等于当前用户ID的文档,无法访问其他用户的条目。
适配你的三类用途
- 替代LDAP跨应用认证:每个应用的用户对应一个MongoDB用户,通过
selfEntryReader角色实现数据隔离,共享数据库的同时保证各应用用户仅能访问自身认证信息。 - 应用配置存储:将配置集合的
entryOwner设为对应应用的用户ID,为应用用户分配该角色,即可确保仅对应应用能访问自身配置。 - 单实例管理多应用:所有应用的用户统一使用该自定义角色,通过
entryOwner字段区分不同应用/项目的数据,无需为每个应用创建独立集合或数据库,大幅简化实例管理。
内容的提问来源于stack exchange,提问作者Rejja Kubzek
相关产品推荐
相关产品推荐

