2016-03-17 41 views
1

我有一個使用Sitecore 7.5和Solr 4.7構建的解決方案。我們需要限制對媒體庫中文檔的搜索,以便它只返回當前登錄用戶(或匿名用戶)有權訪問的文檔。我們當前的解決方案涉及將索引中的拒絕角色和讀取角色列表添加到自定義字段中。然後在查詢時,我們可以構造一個查詢,該查詢只返回用戶所屬的索引中的項目,該查詢至少是Read Roles列表中的一個角色,並且不屬於Denied Roles列表中的任何角色。在Sitecore中如何確定角色是否被明確拒絕讀取項目?

我們遇到的問題(我相信)是如何創建拒絕角色列表。以下是我們在自定義Solr字段中使用的代碼。

public class DenyReadItemRoles : PermissionsRoleBase { 
    protected override object GetPermissibles(ItemSecurity security) { 
     List<string> rolesList = null; 
     using (new Sitecore.SecurityModel.SecurityEnabler()) { 
      var roles = RolesInRolesManager.GetAllRoles(); 
      var denyRoles = roles.Where(r => !security.CanRead(r)); 

      if (denyRoles != null && denyRoles.Any()) { 
       rolesList = denyRoles.Select(r => r.Name).ToList(); 
      } 
     } 
     return rolesList; 
    } 
} 

此代碼使用CanRead()方法確定特定角色是否有權訪問某個項目。這是角色的有效閱讀權利。但是,有時候某個角色可能已被明確拒絕讀取某個項目,有時可能只是刪除了繼承,並且可能根本沒有該項目的任何權限。這是一個微妙的區別。在Sitecore中,如果某個角色被明確拒絕訪問某個項目,那麼該項目應該覆蓋其他項目。在這些情況下,我們目前的代碼工作正常但是在Sitecore中的其他時間,您可能剛剛斷開了繼承並刪除了給定文件夾或項目的所有權限。在這種情況下,角色沒有對該項目的讀取權限,但它不是顯式。因此,在這種情況下,如果用戶屬於可以訪問該項目的其他角色,則用戶應該有權訪問該項目。這是我們的代碼失敗的地方。

所以我問的是這個問題 - 是否有一些其他方式在我的自定義Solr字段,我可以告訴一個角色,只是沒有讀取權限和一個角色明確否認讀取訪問一個物品?

回答

0

我認爲你可能會被迫在你的索引代碼中去樹,以過濾掉非顯式拒絕。一個天真的實現可能看起來像這樣(未經測試)的代碼:

public class ExplicitlyDenyReadItemRoles : PermissionsRoleBase { 
    protected override object GetPermissibles(Item item) { 
     List<string> rolesList = null; 
     using (new Sitecore.SecurityModel.SecurityEnabler()) { 
      var roles = RolesInRolesManager.GetAllRoles(); 
      var denyRoles = roles.Where(r => r.IsDenied(item)); 

      if (denyRoles != null && denyRoles.Any()) { 
       rolesList = denyRoles.Select(r => r.Name).ToList(); 
      } 
     } 
     return rolesList; 
    } 
} 

internal static class SecurityExtensions { 
    internal static bool IsDenied(this Role role, Item item) { 
     if (item.Security.CanRead(role)) return false; 
     AccessRuleCollection accessRules = item.Security.GetAccessRules(); 
     if (accessRules != null) { 
      foreach (AccessRule rule in accessRules) { 
       if (rule.SecurityPermission == SecurityPermission.DenyAccess 
        && rule.AccessRight == AccessRight.ItemRead 
        && rule.Account == role 
        && rule.PropagationType != PropagationType.Entity) { 
        return true; 
       } 
      } 
     } 
     return (item.Parent == null) ? false : role.IsDenied(item.Parent); 
    } 
} 

不完全適合索引性能。請注意,我必須從ItemSecurity更改爲Item,才能「走上樹」。

這裏和其他地方提出的替代方法是在索引後過濾掉結果。但是,當然,這對於分頁結果時的性能並不理想。

密切相關:Indexing Sitecore Item security and restricting returned search results

相關問題