如何以编程方式获取有权访问 SharePoint 中的文件或文件夹的用户和组的列表

How to programmatically get list of users and groups that have access to a file or folder in SharePoint

我正在尝试找到一种方法来获取有权访问已破坏继承的文件夹或文件的 AD 用户和 AD 组的列表。我不需要知道如何找到中断的继承,我已经得到了那部分,但我在查找每个具有访问权限的用户或组时遇到问题。我不想查看 AD 组中有哪些用户,我只想查看正在访问该文件夹的组的名称。这背后的用例是我们不希望将安全文件夹共享给单个用户。所有这些都必须仅由 AD 组控制(站点所有者无权将用户添加到安全文件夹)。还需要找出文件夹中是否有任何文件不是从文件夹继承的,并且也共享给个人用户而不是 AD 组(希望这是有意义的)。这是我到目前为止所拥有的,它在一定程度上起作用,但出于某种原因,它返回了可以在其他地方访问该站点的用户以及访问权限有限的用户,我必须稍后清理。

这是我到目前为止编写的代码,可以正常工作。它接收文件或文件夹的项目对象以及对字符串的引用。它扫描访问,然后构建一个用分号分隔的用户列表,如果 spuser 对象之一是用户而不是组,则 returns 为真:

/// <summary>
    /// Provides list of users\groups that have access to a List Item.
    /// </summary>
    /// <param name="spListItem">Item to check access of</param>
    /// <returns>semi colon delimited list of users\groups with access in a referenced list and boolean value indicating if a direct user exists</returns>
    public bool GetListItemUserAccess(SPListItem spListItem, ref string accountsWithAccess)
    {
        //string accountsWithAccess = string.Empty;
        bool IsFirstIteration = true;
        bool domainUserExits = false;
        SPRoleAssignmentCollection spItemRoles = spListItem.RoleAssignments;    
        SPRoleDefinitionCollection rolesInWeb = spListItem.Web.RoleDefinitions;

        foreach(SPRoleAssignment spRole in spItemRoles)
        {

            SPPrincipal spPrincipal = spRole.Member;

            //cast as SPGroup or SPUser to determine if is a SPGroup or User
            if((spPrincipal as SPGroup) != null)
            {
                SPGroup spGroup = spPrincipal as SPGroup;
                SPUserCollection usersInGroup = spGroup.Users;

                //report on each user in group
                foreach(SPUser spUser in usersInGroup)
                {
                    //check to see if it is a user group
                    if(!spUser.IsDomainGroup)
                    {
                        domainUserExits = true;
                    }

                    //add to list for report.
                    if(IsFirstIteration)
                    {
                        IsFirstIteration = false;                            
                    }
                    else
                    {
                        accountsWithAccess += ";";                            
                    }

                    //depending on the account type sometimes the Login name has the credentials and sometimes it has 
                    //a UID
                    if (spUser.LoginName.ToLower().Contains("<company name>"))
                    {
                        accountsWithAccess += this.ParseUserIDFromClaim(spUser.LoginName);
                    }
                    else
                    {
                        accountsWithAccess += this.ParseUserIDFromClaim(spUser.Name);
                    }
                }
            }
            else if((spPrincipal as SPUser) != null)
            {
                //check to see if the user has limited access only (we don't report on this as this occurs when user has access to something in site)
                  if(!spListItem.DoesUserHavePermissions(spPrincipal as SPUser, SPBasePermissions.ViewListItems))
                {
                    continue;
                }

                //check to see if it is a user group
                if (!(spPrincipal as SPUser).IsDomainGroup)
                {
                    domainUserExits = true;
                }

                //add to list for report.
                if(IsFirstIteration)
                {
                    IsFirstIteration = false;
                }
                else
                {
                    accountsWithAccess += ";";
                }

                //depending on the account type sometimes the Login name has the credentials and sometimes it has 
                //a UID
                if (spPrincipal.LoginName.ToLower().Contains("<company name>"))
                {
                    accountsWithAccess += this.ParseUserIDFromClaim(spPrincipal.LoginName);
                }
                else
                {
                    accountsWithAccess += this.ParseUserIDFromClaim(spPrincipal.Name);
                }
            }
        }
        return domainUserExits;
    }

所以问题是代码返回了有权访问该文件夹的用户或组,但它也返回了其他用户,这些用户对项目的访问权限有限,因为他们可以访问站点内的其他地方。

我终于通过插入以下代码纠正了这个问题:

if (spRole.RoleDefinitionBindings.Count > 1 || !spRole.RoleDefinitionBindings.Xml.ToString().Contains("Limited Access"))

{
  //Process accounts
}

这样做的目的是,如果用户针对列表项绑定了多个角色,或者他们拥有的角色不是“受限访问”,它将处理该帐户。否则,它是其中之一 "phantom accesses" 实际上没有授予对列表项

的直接访问权限