Zone不参与权限控制,权限粒度仅限于Database/Collection;需通过Tag Range+Collection命名+角色绑定模拟Zone级权限,且角色必须在admin库创建并精确限定资源。

分片集群中Zone本身不参与权限控制,权限粒度止于Database/Collection
MongoDB 的 zone 是分片键路由策略的逻辑标签(用于 sh.addShardTag() 和 sh.addTagRange()),它不承载任何访问控制语义。你无法直接给某个 zone 授予或拒绝权限——role 体系里没有 zone 这个作用域。
真正能做权限隔离的,是 database、collection,以及(从 4.2+ 开始)带 resource: { db: "...", collection: "..." } 的自定义角色。如果你的目标是“让 A 组用户只能操作落在 zone: "east" 上的数据”,必须把这种逻辑外移到应用层或通过命名约定+权限绑定实现。
- 确保所有写入该 zone 的数据都写入特定 collection(如
logs_east),再对该 collection 单独授权 - 避免用通配符
collection: ""授权,否则会绕过 zone 意图的隔离效果 - 使用
db.createRole()定义最小权限角色,例如只允许对logs_east执行find和insert
如何用Tag Range + Collection命名 + 角色绑定模拟Zone级权限
典型做法是将 zone 标签与 collection 命名强绑定,并在角色定义中显式限定资源。比如:所有 zone: "us-west" 的数据写入 metrics_us_west,然后创建角色:
db.createRole({
role: "metrics_us_west_reader",
privileges: [{
resource: { db: "monitoring", collection: "metrics_us_west" },
actions: ["find"]
}],
roles: []
})
注意:sh.addTagRange() 只影响数据分布,不影响认证;而 createRole() 中的 resource 字段必须精确匹配实际 collection 名,大小写敏感,且不能是正则或通配符。
- 不要试图在
resource中填collection: "metrics_*"—— MongoDB 不支持 glob 或 regex 匹配 - 如果业务需要动态 zone 映射,建议由应用在写入前根据 region 决定 collection 名,而非依赖分片键自动路由后做权限拦截
- 启用
security.authorization: enabled后,所有连接必须带凭据,否则连listDatabases都会被拒绝
分片集群下角色必须在admin库创建,且对config server无特殊权限
在 sharded cluster 中,自定义角色必须在 admin 数据库中创建(use admin 后执行 createRole),这是硬性要求。角色定义本身不会自动同步到 config server,但其生效依赖于 mongos 路由时携带的认证上下文——也就是说,用户连接的是 mongos,角色信息由 mongos 从 config server 的 system.roles 读取并校验。
- 不要在 shard 的本地
admin库中创建角色——它只对直连该 shard 有效,对 mongos 无效 - config server 的
system.roles是只读视图,不可直接写入;所有角色增删改必须经由 mongos 执行 - 若使用 LDAP 或 x.509 认证,角色映射需在外部系统配置,MongoDB 仅消费映射结果
容易被忽略的坑:readPreference 和 writeConcern 会影响权限感知路径
当用户通过 mongos 连接并拥有某 collection 权限时,看似没问题;但如果应用代码显式设置了 readPreference: "primaryPrefered" 或直连某个 shard(绕过 mongos),权限检查就可能失效——因为 shard 节点不维护全局角色视图,也不执行跨分片的权限聚合。
- 始终通过 mongos 连接,禁用客户端直连 shard 的连接字符串
- 在连接驱动中显式指定
readPreference: "secondaryPreferred"时,确保对应 secondary 也运行在 auth 模式下(否则可能降级为无鉴权读取) - 使用
writeConcern: { w: "majority" }时,权限检查发生在 primary,但写入传播到其他节点不触发二次鉴权——所以权限必须在 primary 上完备
Zone 是数据分布概念,权限是访问控制概念;强行混用两者,往往意味着模型错位。最稳妥的方式,是让 zone 策略服务于运维目标(如就近读、冷热分离),而把权限边界落在 collection 层级,并用清晰的命名和自动化脚本约束开发行为。


















