检查给定用户是否在给定路径的安全组中

时间:2014-08-28 14:25:05

标签: security active-directory directory ldap filesystems

我有一份简单的工作,我不知道如何完成,而且随着我的搜索越来越深入,我越来越深。

我需要编写一个方法,在给定的文件夹路径上返回给定用户的FileSystemAccessRule(我给他的samAccountName,objectGUID)。

我已经在此之前添加或删除了FileSystemAccessRule之前的路径:

var fSecurity = Directory.GetAccessControl(physicalPath);

fSecurity.AddAccessRule(new FileSystemAccessRule(samAccountName, FileSystemRights.FullControl, AccessControlType.Allow));
fSecurity.RemoveAccessRule(new FileSystemAccessRule(samAccountName, FileSystemRights.FullControl, AccessControlType.Allow));

Directory.SetAccessControl(physicalPath, fSecurity);

检查给定用户是否具有某个类似路径的访问权限?或者应该采取另一种方式?类似于DirectoryEntryLDAPActive Directory左右?

我想要的是一种可能如下所示的方法:

FileSystemAccessRule[] GetAccessRulesOfTheUserOverPath(string samAccountName, string folderPath)
{
    /// how?
}

1 个答案:

答案 0 :(得分:0)

感谢你的一些答案,我想出了答案。虽然这不是我的问题的确切答案,但它满足了我的需要。在this question的答案中,我找到了解决方案。此解决方案告诉我给定的FileSystemRights是否绑定到给定文件夹的acl(AuthorizationRuleCollection)上的当前Windows用户。

我所提到的问题中的几乎所有答案都给出了结果。在我看来,最准确的答案是@Olivier Jacot-Descombes的答案,因为它计算了允许规则,拒绝规则,以及继承规则优先于彼此。

所以我做的是:

WindowsIdentity _currentUser;
WindowsPrincipal _currentPrincipal;

using ( new Impersonator(userName, passwordOfTheUser) )
{
    _currentUser = WindowsIdentity.GetCurrent();
    _currentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
}

if ( !Directory.Exists(path) ) throw new Exception("Directory does not exist");

var di = new DirectoryInfo(path);

var directoryACLs = di.GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));

///rw_accessRules list consists of the rules for ReadWrite permissons.
bool auth_RW = rw_accessRules.All(aR => HasFileOrDirectoryAccess(_currentUser, _currentPrincipal, aR, directoryACLs)); 

这是``HasFileOrDirectoryAccess`方法:

bool HasFileOrDirectoryAccess ( WindowsIdentity _currentUser, WindowsPrincipal _currentPrincipal, FileSystemRights right, AuthorizationRuleCollection acl )
{
    bool allow = false;
    bool inheritedAllow = false;
    bool inheritedDeny = false;

    foreach ( FileSystemAccessRule currentRule in acl )
    {
        // If the current rule applies to the current user.
        if ( _currentUser.User.Equals(currentRule.IdentityReference) || _currentPrincipal.IsInRole((SecurityIdentifier)currentRule.IdentityReference) )
        {
            if ( currentRule.AccessControlType.Equals(AccessControlType.Deny) )
            {
                if ( ( currentRule.FileSystemRights & right ) == right )
                {
                    if ( currentRule.IsInherited )
                    {
                        inheritedDeny = true;
                    }
                    else
                    { // Non inherited "deny" takes overall precedence.
                        return false;
                    }
                }
            }
            else if ( currentRule.AccessControlType.Equals(AccessControlType.Allow) )
            {
                if ( ( currentRule.FileSystemRights & right ) == right )
                {
                    if ( currentRule.IsInherited )
                    {
                        inheritedAllow = true;
                    }
                    else
                    {
                        allow = true;
                    }
                }
            }
        } 
    }


    if ( allow )
    { // Non inherited "allow" takes precedence over inherited rules.
        return true;
    }
    return inheritedAllow && !inheritedDeny;
}

我首先模仿给定用户,获取他的主体和身份,然后检查他是否具有给定规则集的权限。

这个适用于我的情况,但您会注意到我们需要用户的密码来检查权限。如果没有密码就有办法做到这一点,那就太好了。