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
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.