Solr动态文档权限控制最佳实践咨询:基于用户ID与用户组
针对你这个Solr文档权限控制的需求,结合你提到的原子更新效率低的痛点,我给你整理几个生产环境中验证过的最佳实践,都是兼顾灵活性和性能的方案:
1. 基于角色/组粒度的字段过滤(最常用、轻量)
这是最直接的方案,核心思路是把权限信息作为文档的字段存储,查询时通过Filter Query(fq)过滤出用户有权限访问的文档,但我们要避开直接存储用户ID的坑,改用「用户组+特殊用户组」的方式:
- 给你的文档添加一个多值字段
AllowedGroups,用来存储允许访问的组ID,或者把单个用户ID当成特殊的「个人组」(比如user_1、user_2)。比如你的示例文档可以修改成:
{ "Id":"10000093", "Active":true, "Title":"Title", "ShortDescription":"ShortDescription", "Order":5, "Categories":["Category 1", "Category 2"], "Keywords":["Keyword 1", "Keyword 2"], "AllowedGroups": ["user_1", "user_2", "user_3"], // 仅对这三个用户可见 "_version_":1620359096543739904 }
而premium组可见的文档,AllowedGroups就设为["premium"]。
- 用户查询时,先从你的用户服务获取该用户所属的所有组(包括他自己的「个人组」,比如用户ID是1就加上
user_1),然后在Solr查询中添加Filter Query:fq=AllowedGroups:(user_1 OR premium OR ...)
为什么比原子更新优?
- 用户的组信息变更时,完全不需要修改Solr里的任何文档,只需要在查询时传入更新后的组列表即可;
- 文档权限变更时,只需要更新该文档的
AllowedGroups字段(哪怕用原子更新,也是单个文档的操作,批量变更的话可以用Solr的批量更新API一次性提交多个文档的修改,比一个个发原子更新请求高效太多); - 性能上,把
AllowedGroups设为indexed=true, docValues=true, stored=false,Solr的Filter Query会利用docValues快速过滤,不会成为查询瓶颈。
2. 独立权限Core + Join查询(适合复杂权限场景)
如果你的权限规则非常复杂(比如支持角色继承、多维度权限组合),或者需要频繁批量调整文档权限,单独维护一个权限Core会更灵活:
- 创建一个专门的
permissionsCore,里面的文档结构极简,只存权限关联关系:
// 用户-文档关联 { "permissionId": "p1", "subjectType": "user", "subjectId": "1", "docId": "10000093" } // 组-文档关联 { "permissionId": "p2", "subjectType": "group", "subjectId": "premium", "docId": "10000094" }
- 用户查询时,用Solr的Join查询关联主文档Core和权限Core:
q=*:*&fq={!join from=docId to=Id}(subjectType:user AND subjectId:1) OR (subjectType:group AND subjectId:premium)
优势:
- 主文档完全不需要携带权限信息,权限变更只在
permissionsCore里操作,Core轻量,更新速度极快; - 支持复杂的权限规则,比如可以给权限记录加有效期、权限类型等字段,拓展性极强;
- 用户或组的权限变更,只需要在
permissionsCore里添加/删除对应记录,不影响主文档的索引稳定性。
3. 强制权限过滤的保障措施
不管用哪种方案,都要确保权限过滤不会被绕过:
- 在应用层封装Solr查询,强制给每个查询加上权限Filter Query,不要让前端直接构造Solr请求;
- 或者在Solr的Request Handler里配置默认的
fq参数,结合Solr的Security插件,让只有经过认证的请求才能访问,并且自动注入用户的权限条件(不过这个需要定制开发); - 把权限相关字段设为
stored=false,避免在查询结果中泄露权限规则。
为什么不推荐纯原子更新?
你担心的原子更新效率低是对的——如果要给1000个文档添加premium权限,一个个发原子更新请求会产生大量的HTTP请求,而且每个请求都要更新索引,性能开销很大。而上面的方案要么批量更新文档字段,要么在独立权限Core里批量添加关联记录,效率提升非常明显。
内容的提问来源于stack exchange,提问作者wydy
相关产品推荐
相关产品推荐

