为Sitecore项目安全性编制索引并限制返回的搜索结果 [英] Indexing Sitecore Item security and restricting returned search results

查看:67
本文介绍了为Sitecore项目安全性编制索引并限制返回的搜索结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了几个角色,每个角色对内容和媒体项都有不同的限制,我想根据当前登录用户的访问权限来限制返回的搜索结果,而不是显示结果和用户然后显示访问被拒绝"页面.显然,某些内容可以由Extranet \匿名访问,因此无论如何,所有用户都应返回它们.

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 access rights of the currently logged in user, rather than displaying the result and the user then presented with an "Access Denied" page. Some content will obviously be accessible to extranet\anonymous so they should be returned for all users regardless.

安全性遵循标准 Sitecore做法因此将使用角色继承(角色内的角色),因此还需要考虑到这一点.

The security follows the standard Sitecore practices so Role inheritance (roles within roles) will be used, so it will need to take this into account also.

高级数据库抓取程序模块中,我看不到任何内容会有所帮助,我已经浏览了《 Sitecore搜索和索引指南》(版本7 ),但找不到有关为项目应用的安全性编制索引的任何信息.以下文章有一些建议:

I couldn't see anything in the Advanced Database Crawler module that would help and I've looked through the Sitecore Search and Indexing Guide (version 6.6 and version 7) but couldn't find any information about indexing the security applied to items. The following articles have some suggestions:

  • 如何可以在Sitecore中设置可以正确处理安全性的Lucene索引吗?

这感觉很脏",并可能导致性能问题,特别是在退回大量物品时.另外,(请参阅评论)分页结果的问题.

This feels "dirty" and has the potential for performance issues, particularly when there are a large number of items returned. Also, (see in the comments) the issue with paging results.

以上内容看起来更切合实际,并且将根据索引的安全角色过滤掉结果,显然需要扩展角色以处理角色中的角色.我的担心是,当我们特别需要拒绝/限制对某些角色对内容项的访问时,我们将需要处理拒绝的权限(我知道不建议这样做,但是有一个非常具体的需要始终拒绝).

The above looks more realistic, and would filter out the results based on indexed security roles, there would obviously be a need to expand the roles to handle roles within roles. My concern here would be that we would need to handle denied permissions, when we specifically need to deny/restrict access for certain roles to content items (I know this is not recommended practice, but there is a very specific need to always deny).

我目前正处于计划阶段,所以今天发布Sitecore 7的同时,也可以使用更新的Lucene库和/或SOLR,如果这样可以使工作变得更轻松-当然,假设某些模块例如面向营销人员的WebForms

I'm at the planning stage at the moment so with the release of Sitecore 7 today there is also the possibility to use the updated Lucene libraries and/or SOLR if that makes life easier - assuming of course that some of the modules like WebForms for Marketers and Email Campaign Manager are updated before too long.

考虑到安全性,人们用于返回搜索结果的解决方案有哪些?除了上面链接的问题以外,还有其他选择吗?也许我可以利用Sitecore 7中的某些东西,例如更新的Lucene库或SOLR?

What are the solutions that people are using for returning search results taking into account security? Any alternatives than the linked questions above? Maybe something in Sitecore 7 that I can leverage, the updated Lucene libraries or SOLR?

我希望保留所有这些开箱即用"的Sitecore,并且尽可能不使用其他第三方搜索产品.

I'd prefer to keep this all "out of the box" Sitecore and not use other third party search products if at all possible.

推荐答案

与克劳斯的建议略有不同:

A slight alternative to the suggestion from Klaus:

Sitecore.ContentSeach.config中,您将找到一个名为contentSearch.getGlobalSearchFilters

In Sitecore.ContentSeach.config you'll find a pipeline called contentSearch.getGlobalSearchFilters

添加到此管道中的处理器将应用于任何查询,因此,如果我们添加一个根据角色应用过滤器的处理器,那么我们很好.

Processors added to this pipeline will be applied to any query, so if we drop in one that applies a filter based on roles we're good.

首先,我们希望将计算字段添加到索引配置中:

To start, we want a computed field added to our index configuration:

<fields hint="raw:AddComputedIndexField">
   <field fieldName="read_roles"           returnType="stringCollection">Sitecore.ContentSearch.ComputedFields.ReadItemRoles,Sitecore.ContentSearch</field>
</fields>

注意,存储的类型是字符串的集合.我们将使用它来索引可以读取项目的所有角色名称.

NOTE the stored type is a collection of strings. We'll use it to index all the names of roles that can read an item.

  1. 我们有一个基本的抽象类来处理项目安全性详细信息的提取

  1. We have a base abstract class to handle the extraction of item security details

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);
}

  • 我们用抽象方法实现了以上

  • We implement the above with the abstracted method

    public class ReadItemRoles : ItemPermissions
    {
        protected override object GetPermissibles(ItemSecurity security)
        {
            var roles = RolesInRolesManager.GetAllRoles();
            return roles.Where(security.CanRead).Select(r => r.Name);
        }
    }
    

  • 注意在这里显然会对性能产生影响,这会降低索引速度. 为了减少影响,仅将计算字段添加到包含受保护内容的索引的索引配置中.例如.如果您的Web内容仅由匿名用户访问,则不会带来任何好处.

    NOTE There's obviously a performance impact here, this will reduce your indexing speed. To reduce the impact, only add the the computed field to the index configuration for the index that contains secured content. E.g. If your web content is only accessed by the anonymous user it will add no benefit.

    将条目添加到配置中

    <contentSearch.getGlobalSearchFilters>
        <processor type="Sitecore.ContentSearch.Pipelines.GetGlobalFilters.ApplyGlobalReadRolesFilter, Sitecore.ContentSearch" />
      </contentSearch.getGlobalSearchFilters>
    

    实施

    实施管道过滤器以检查上下文用户的角色

    Implementation

    Implement the pipeline filter to check the roles of the context user

    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);
        }
    }
    

    摘要

    1. 创建一个ComputedField,它返回给定访问权限的所有有效角色的列表
    2. 将管道处理器应用于contentSearch.getGlobalSearchFilters,以向每个搜索请求添加查询过滤器.
    3. 使用PredicateBuilder类以确保将角色名称进行或"运算
    1. Create a ComputedField that returns a list of all valid roles for a given access right
    2. Apply a pipeline processor to contentSearch.getGlobalSearchFilters to add a query filter to each search request.
    3. Use the PredicateBuilder class to ensure the role names are OR'ed together

    这里最大的好处是您可以在索引时间进行匹配,并且像往常一样通过搜索查询来处理项目限制.无需担心构面编号或搜索计数不正确.

    The big benefit here is that you take the hit at index time and the handling of item restriction is handled through a search query as normal. No need to worry about the facet numbers or search counts being incorrect.

    您可以限制为计算字段而要检查的角色,并且可以更改管道过滤器的应用.您甚至可以删除管道过滤器,仅在需要时更新查询以进行过滤.

    You can restrict the roles you are checking to compute the field and you can vary the application of the pipeline filter. You can even take out the pipeline filter and just update your queries to filter when you require it.

    注意与此设置有关的最大问题是,当安全性限制发生变化时,要求重新索引您的内容.如果您要对用户本身应用安全限制,则必须包括其他计算字段.

    NOTE The biggest problem with this set up is the requirement to re-index your content when security restrictions change. Should you be applying security restrictions to users themselves, you'll have to include additional computed fields.

    编辑02/06/2013

    我只是在项目中对此进行了修改,并且意识到它正在与查询中的角色进行与"运算.如果用户分配了多个角色,则这两个角色都必须具有对该项目的声明权限.我已经更新了管道处理器,以使用

    I was just tinkering with this in a project and realised that it was AND'ing the roles in the query. If a user had multiple roles assigned then both roles would have to have declared rights to the item. I've updated the pipeline processor to use the PredicateBuilder class to OR the roles. A check is also added to ensure the predicate is not a constant, this ensures the query is updated only if we have a filter to apply.

    这篇关于为Sitecore项目安全性编制索引并限制返回的搜索结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆