Indexing Sitecore Item security and restricting returned search results

前端 未结 4 895
梦谈多话
梦谈多话 2020-12-05 16:14

I have several roles defined, each with different restrictions to content and media items and I would like to restrict the search results that are returned based on the acce

4条回答
  •  南方客
    南方客 (楼主)
    2020-12-05 16:39

    After some more searching around, the Linq to Sitecore article pointed me to the following lines of code:

    var index = SearchManager.GetIndex("sitecore_master_index");
    var context = index.CreateSearchContext(SearchSecurityOptions.EnableSecurityCheck))
    

    Digging through Sitecore.ContentSearch.dll and Sitecore.ContentSearch.LuceneProvider.dll in dotPeek decompiler and the mention of the indexing.filterIndex.outbound pipeline in the Sitecore 7 Search document I found the following code:

    Sitecore.ContentSearch.LuceneProvider.LuceneSearchReults

    public IEnumerable> GetSearchHits()
    {
      for (int idx = this.startIndex; idx <= this.endIndex; ++idx)
      {
        Document doc = this.context.Searcher.IndexReader.Document(this.searchHits.ScoreDocs[idx].Doc, (FieldSelector) this.fieldSelector);
        if (!this.context.SecurityOptions.HasFlag((Enum) SearchSecurityOptions.DisableSecurityCheck))
        {
          string secToken = doc.GetField("_uniqueid").StringValue;
          string dataSource = doc.GetField("_datasource").StringValue;
          if (!string.IsNullOrEmpty(secToken))
          {
            bool isExcluded = OutboundIndexFilterPipeline.CheckItemSecurity(new OutboundIndexFilterArgs(secToken, dataSource));
            if (!isExcluded)
              yield return new SearchHit(this.searchHits.ScoreDocs[idx].Score, this.configuration.IndexDocumentPropertyMapper.MapToType(doc, this.selectMethod, this.virtualFieldProcessors, this.context.SecurityOptions));
          }
        }
        else
          yield return new SearchHit(this.searchHits.ScoreDocs[idx].Score, this.configuration.IndexDocumentPropertyMapper.MapToType(doc, this.selectMethod, this.virtualFieldProcessors, this.context.SecurityOptions));
      }
    }
    

    Sitecore.ContentSearch.Pipelines.IndexingFilters

    public class ApplyOutboundSecurityFilter : OutboundIndexFilterProcessor
    {
        public override void Process(OutboundIndexFilterArgs args)
        {
          if (args.IndexableUniqueId == null || !(args.IndexableDataSource == "Sitecore"))
            return;
          ItemUri uri = new ItemUri(args.IndexableUniqueId);
          if (args.AccessRight != AccessRight.ItemRead || Database.GetItem(uri) != null)
            return;
          args.IsExcluded = true;
        }
    }
    

    So it looks like Sitecore 7 gives us the ability to filter the the search results using the security rights of the context user straight out of the box, albeit using a very similar method of checking the item read permissions that Mark Cassidy suggested. Which is good news, since if this is a requirement for Sitecore 6 implementations then we can easily update the Advanced Database Crawler to do the same thing.

    I'm still not convinced on the performance of this though, given that Sitecore 7 comes with Item Buckets and the possibility of storing millions of items. It should be possible to create several indexes though, and only EnableSecurityCheck on indexes with security enabled content, but then we need to think about combining the results from several indexes for "global search" results and also take into acccount Boosting which will mean re-ordering the combined results.

提交回复
热议问题