jam*_*kam 10 security lucene solr sitecore sitecore7
我定义了几个角色,每个角色对内容和媒体项都有不同的限制,我想限制根据当前登录用户的访问权限返回的搜索结果,而不是显示结果,然后显示用户"拒绝访问"页面.外网\匿名显然可以访问某些内容,因此无论如何都应该为所有用户返回它们.
安全性遵循标准的Sitecore实践,因此将使用角色继承(角色中的角色),因此还需要考虑这一点.
我在Advanced Database Crawler模块中看不到任何有用的东西,我查看了Sitecore搜索和索引指南(版本6.6和版本7),但找不到有关索引应用于项目的安全性的任何信息.以下文章有一些建议:
这感觉"很脏",并且可能会出现性能问题,尤其是在返回大量商品时.另外,(在评论中看到)分页结果的问题.
上面看起来更加真实,并且会根据索引的安全角色过滤掉结果,显然需要扩展角色来处理角色中的角色.我在这里担心的是,当我们特别需要拒绝/限制某些角色对内容项的访问时,我们需要处理被拒绝的权限(我知道这不是推荐的做法,但是有一个非常具体的需要总是拒绝).
我现在处于计划阶段,所以今天发布Sitecore 7还有可能使用更新的Lucene库和/或SOLR,如果这样可以让生活变得更轻松 - 当然假设某些模块像WebForms for营销人员和电子邮件营销经理会在不久之前更新.
考虑到安全性,人们用于返回搜索结果的解决方案是什么?除上述相关问题之外的其他选择?也许我可以利用Sitecore 7中的东西,更新的Lucene库或SOLR?
我宁愿保持这一切"开箱即用"Sitecore,如果可能的话,不要使用其他第三方搜索产品.
Kie*_*ies 14
克劳斯的建议略有替代:
在Sitecore.ContentSeach.config你找到一个叫做的管道contentSearch.getGlobalSearchFilters
添加到此管道的处理器将应用于任何查询,因此如果我们放入一个基于角色应用过滤器的处理器,那么我们就是好的.
首先,我们想要一个计算字段添加到我们的索引配置:
<fields hint="raw:AddComputedIndexField">
<field fieldName="read_roles" returnType="stringCollection">Sitecore.ContentSearch.ComputedFields.ReadItemRoles,Sitecore.ContentSearch</field>
</fields>
Run Code Online (Sandbox Code Playgroud)
注意存储的类型是字符串的集合.我们将使用它来索引可以读取项目的角色的所有名称.
我们有一个基本抽象类来处理项目安全性细节的提取
public abstract class ItemPermissions: IComputedIndexField
{
public string FieldName { get; set; }
public string ReturnType { get; set; }
public object ComputeFieldValue(IIndexable indexable)
{
var indexableItem = indexable as SitecoreIndexableItem;
if (indexableItem == null) return null;
var security = indexableItem.Item.Security;
return GetPermissibles(security);
}
protected abstract object GetPermissibles(ItemSecurity security);
}
Run Code Online (Sandbox Code Playgroud)我们使用抽象方法实现上述内容
public class ReadItemRoles : ItemPermissions
{
protected override object GetPermissibles(ItemSecurity security)
{
var roles = RolesInRolesManager.GetAllRoles();
return roles.Where(security.CanRead).Select(r => r.Name);
}
}
Run Code Online (Sandbox Code Playgroud)注意这里显然会产生性能影响,这会降低您的索引速度.要减少影响,只需将计算字段添加到包含安全内容的索引的索引配置中.例如,如果您的Web内容仅由匿名用户访问,则不会增加任何好处.
将条目添加到配置中
<contentSearch.getGlobalSearchFilters>
<processor type="Sitecore.ContentSearch.Pipelines.GetGlobalFilters.ApplyGlobalReadRolesFilter, Sitecore.ContentSearch" />
</contentSearch.getGlobalSearchFilters>
Run Code Online (Sandbox Code Playgroud)
实现管道过滤器以检查上下文用户的角色
public class ApplyGlobalReadRolesFilter : GetGlobalFiltersProcessor
{
public override void Process(GetGlobalFiltersArgs args)
{
var query = (IQueryable<SitecoreUISearchResultItem>)args.Query;
var userRoles = Context.User.Roles.Select(r => r.Name.Replace(@"\", @"\\"));
var predicate = PredicateBuilder.True<SitecoreUISearchResultItem>();
predicate = userRoles.Aggregate(predicate, (current, role) => current.Or(i => i["read_roles"].Contains(role)));
if(predicate.Body.NodeType != ExpressionType.Constant)
args.Query = query.Filter(predicate);
}
}
Run Code Online (Sandbox Code Playgroud)
contentSearch.getGlobalSearchFilters向每个搜索请求添加查询过滤器.PredicateBuilder该类可确保将角色名称组合在一起这里的最大好处是您可以在索引时获取命中,并且正常情况下通过搜索查询处理项目限制.无需担心方面数字或搜索计数不正确.
您可以限制要检查的角色来计算字段,并且可以改变管道过滤器的应用程序.您甚至可以取出管道过滤器,只需更新您的查询即可在需要时进行过滤.
注意 此设置的最大问题是在安全限制发生更改时需要重新索引内容.如果您对用户自己应用安全限制,则必须包含其他计算字段.
编辑02/06/2013
我只是在一个项目中修补它,并意识到它是在查询中的角色.如果用户分配了多个角色,则两个角色都必须具有该项的声明权限.我已经更新了管道处理器以使用PredicateBuilder该类来管理角色.还会添加一个检查以确保谓词不是常量,这样可以确保只有在我们要应用过滤器时才更新查询.
经过更多搜索后,Linq to Sitecore文章向我指出了以下代码行:
var index = SearchManager.GetIndex("sitecore_master_index");
var context = index.CreateSearchContext(SearchSecurityOptions.EnableSecurityCheck))
Run Code Online (Sandbox Code Playgroud)
在dotPeek反编译器和Sitecore 7 搜索文档中提到的管道中进行挖掘Sitecore.ContentSearch.dll和挖掘,我发现了以下代码:Sitecore.ContentSearch.LuceneProvider.dllindexing.filterIndex.outbound
Sitecore.ContentSearch.LuceneProvider.LuceneSearchReults
public IEnumerable<SearchHit<TElement>> 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<TElement>(this.searchHits.ScoreDocs[idx].Score, this.configuration.IndexDocumentPropertyMapper.MapToType<TElement>(doc, this.selectMethod, this.virtualFieldProcessors, this.context.SecurityOptions));
}
}
else
yield return new SearchHit<TElement>(this.searchHits.ScoreDocs[idx].Score, this.configuration.IndexDocumentPropertyMapper.MapToType<TElement>(doc, this.selectMethod, this.virtualFieldProcessors, this.context.SecurityOptions));
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,看起来 Sitecore 7 使我们能够直接使用上下文用户的安全权限过滤搜索结果,尽管使用了与Mark Cassidy建议的检查项目读取权限非常相似的方法。这是个好消息,因为如果这是 Sitecore 6 实现的要求,那么我们可以轻松更新高级数据库爬虫来做同样的事情。
不过,鉴于 Sitecore 7 带有 Item Buckets 以及存储数百万个项目的可能性,我仍然不相信它的性能。虽然应该可以创建多个索引,并且只能EnableSecurityCheck在具有启用安全性的内容的索引上创建,但是我们需要考虑将来自多个索引的结果组合起来以获得“全局搜索”结果,并考虑帐户提升,这意味着重新排序合并的结果。
| 归档时间: |
|
| 查看次数: |
3827 次 |
| 最近记录: |