C#测试用户是否具有文件夹的写入权限

Chr*_*s B 179 c# directory permissions

我需要测试用户是否可以在实际尝试之前写入文件夹.

我已经实现了以下方法(在C#2.0中),它尝试使用Directory.GetAccessControl()方法检索文件夹的安全权限.

private bool hasWriteAccessToFolder(string folderPath)
{
    try
    {
        // Attempt to get a list of security permissions from the folder. 
        // This will raise an exception if the path is read only or do not have access to view the permissions. 
        System.Security.AccessControl.DirectorySecurity ds = Directory.GetAccessControl(folderPath);
        return true;
    }
    catch (UnauthorizedAccessException)
    {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在谷歌搜索如何测试写入访问时,没有出现这样的情况,实际测试Windows中的权限似乎非常复杂.我担心我过度简化了事情并且这种方法并不健全,尽管它似乎确实有效.

我的方法是否可以测试当前用户是否具有写访问权限?

Dun*_*owe 62

我很欣赏这篇帖子的当天晚些时候,但您可能会发现这段代码很有用.

string path = @"c:\temp";
string NtAccountName = @"MyDomain\MyUserOrGroup";

DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));

//Go through the rules returned from the DirectorySecurity
foreach (AuthorizationRule rule in rules)
{
    //If we find one that matches the identity we are looking for
    if (rule.IdentityReference.Value.Equals(NtAccountName,StringComparison.CurrentCultureIgnoreCase))
    {
        var filesystemAccessRule = (FileSystemAccessRule)rule;

        //Cast to a FileSystemAccessRule to check for access rights
        if ((filesystemAccessRule.FileSystemRights & FileSystemRights.WriteData)>0 && filesystemAccessRule.AccessControlType != AccessControlType.Deny)
        {
            Console.WriteLine(string.Format("{0} has write access to {1}", NtAccountName, path));
        }
        else
        {
            Console.WriteLine(string.Format("{0} does not have write access to {1}", NtAccountName, path));
        }
    }
}

Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

将其放入控制台应用程序,看看它是否满足您的需求.

  • 您需要添加对 FileSystemAccessRule 类型的检查。如果是拒绝规则,您将错误地将其报告为可写。 (2认同)
  • 我正在尝试使用它。发现了另一个问题。如果仅将权限分配给组而不是特定用户,这将错误地报告他们没有写访问权。例如,授予“授权用户”的写访问权限 (2认同)

Ash*_*Ash 59

这是在C#中检查文件夹访问权限的完全有效的方法.它可能失败的唯一地方是如果你需要在一个紧凑的循环中调用它,其中异常的开销可能是一个问题.

之前还有其他类似的 问题.

  • 这不会告诉您是否拥有写入权限,它只会告诉您是否可以查找该文件夹的权限.您也可以编写但无法查找权限. (11认同)

小智 58

public bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
{
    try
    {
        using (FileStream fs = File.Create(
            Path.Combine(
                dirPath, 
                Path.GetRandomFileName()
            ), 
            1,
            FileOptions.DeleteOnClose)
        )
        { }
        return true;
    }
    catch
    {
        if (throwIfFails)
            throw;
        else
            return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @GY,`string tempFileName = Path.GetRandomFileName();`,显然 (7认同)
  • 此答案将捕获尝试写入文件时可能发生的所有异常,而不仅仅是权限违规. (6认同)
  • 从我在下面尝试的所有替代方案(和引用的链接) - 这是唯一可靠的工作. (4认同)
  • 然而,@Matt,无论失败的原因如何,这都回答了问题"目录是否可写".你宁愿回答"**为什么**我不能写到目录".:) (3认同)

JGU*_*JGU 21

我尝试了大部分这些,但是它们给出了误报,所有这些都是出于同样的原因.仅仅测试目录的可用权限是不够的,你必须检查登录用户是否是具有该权限的组的成员允许.为此,您将获得用户标识,并检查它是否是包含FileSystemAccessRule IdentityReference的组的成员.我测试了这个,完美无缺地工作..

    /// <summary>
    /// Test a directory for create file access permissions
    /// </summary>
    /// <param name="DirectoryPath">Full path to directory </param>
    /// <param name="AccessRight">File System right tested</param>
    /// <returns>State [bool]</returns>
    public static bool DirectoryHasPermission(string DirectoryPath, FileSystemRights AccessRight)
    {
        if (string.IsNullOrEmpty(DirectoryPath)) return false;

        try
        {
            AuthorizationRuleCollection rules = Directory.GetAccessControl(DirectoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
            WindowsIdentity identity = WindowsIdentity.GetCurrent();

            foreach (FileSystemAccessRule rule in rules)
            {
                if (identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((AccessRight & rule.FileSystemRights) == AccessRight)
                    {
                        if (rule.AccessControlType == AccessControlType.Allow)
                            return true;
                    }
                }
            }
        }
        catch { }
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

  • AccessControlType deny 优先于允许,因此要完全彻底的拒绝访问权限的规则也应该检查,并且在检查拒绝类型时它应该是 `(AccessRight &amp; rule.FileSystemRights) &gt; 0` 因为任何子访问类型被拒绝这是`AccessRight` 的一部分意味着您没有对`AccessRight` 的*完全* 访问权限 (2认同)

UGE*_*EEN 13

例如,对于所有用户(Builtin\Users),此方法工作正常 - 享受.

public static bool HasFolderWritePermission(string destDir)
{
   if(string.IsNullOrEmpty(destDir) || !Directory.Exists(destDir)) return false;
   try
   {
      DirectorySecurity security = Directory.GetAccessControl(destDir);
      SecurityIdentifier users = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
      foreach(AuthorizationRule rule in security.GetAccessRules(true, true, typeof(SecurityIdentifier)))
      {
          if(rule.IdentityReference == users)
          {
             FileSystemAccessRule rights = ((FileSystemAccessRule)rule);
             if(rights.AccessControlType == AccessControlType.Allow)
             {
                    if(rights.FileSystemRights == (rights.FileSystemRights | FileSystemRights.Modify)) return true;
             }
          }
       }
       return false;
    }
    catch
    {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*rov 11

恕我直言,唯一100%可靠的方法来测试你是否可以写入目录是实际写入它并最终捕获异常.


小智 8

试试这个:

try
{
    DirectoryInfo di = new DirectoryInfo(path);
    DirectorySecurity acl = di.GetAccessControl();
    AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));

    WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(currentUser);
    foreach (AuthorizationRule rule in rules)
    {
        FileSystemAccessRule fsAccessRule = rule as FileSystemAccessRule;
        if (fsAccessRule == null)
            continue;

        if ((fsAccessRule.FileSystemRights & FileSystemRights.WriteData) > 0)
        {
            NTAccount ntAccount = rule.IdentityReference as NTAccount;
            if (ntAccount == null)
            {
                continue;
            }

            if (principal.IsInRole(ntAccount.Value))
            {
                Console.WriteLine("Current user is in role of {0}, has write access", ntAccount.Value);
                continue;
            }
            Console.WriteLine("Current user is not in role of {0}, does not have write access", ntAccount.Value);                        
        }
    }
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("does not have write access");
}
Run Code Online (Sandbox Code Playgroud)


Vin*_*jip 6

您的代码获取DirectorySecurity给定目录,并正确处理异常(由于您无法访问安全信息).但是,在您的示例中,您实际上并不询问返回的对象以查看允许访问的内容 - 我认为您需要添加此内容.


sdd*_*dds 6

这是CsabaS答案的修改版本,它解释了明确的拒绝访问规则.该函数遍历目录的所有FileSystemAccessRules,并检查当前用户是否具有可访问目录的角色.如果未找到此类角色或用户处于拒绝访问的角色,则该函数返回false.要检查读取权限,请将FileSystemRights.Read传递给该函数; 对于写权限,传递FileSystemRights.Write.如果要检查任意用户的权限而不是当前用户的权限,请将currentUser WindowsIdentity替换为所需的WindowsIdentity.我还建议不要依赖这样的函数来确定用户是否可以安全地使用该目录.这个答案完美地解释了原因

    public static bool UserHasDirectoryAccessRights(string path, FileSystemRights accessRights)
    {
        var isInRoleWithAccess = false;

        try
        {
            var di = new DirectoryInfo(path);
            var acl = di.GetAccessControl();
            var rules = acl.GetAccessRules(true, true, typeof(NTAccount));

            var currentUser = WindowsIdentity.GetCurrent();
            var principal = new WindowsPrincipal(currentUser);
            foreach (AuthorizationRule rule in rules)
            {
                var fsAccessRule = rule as FileSystemAccessRule;
                if (fsAccessRule == null)
                    continue;

                if ((fsAccessRule.FileSystemRights & accessRights) > 0)
                {
                    var ntAccount = rule.IdentityReference as NTAccount;
                    if (ntAccount == null)
                        continue;

                    if (principal.IsInRole(ntAccount.Value))
                    {
                        if (fsAccessRule.AccessControlType == AccessControlType.Deny)
                            return false;
                        isInRoleWithAccess = true;
                    }
                }
            }
        }
        catch (UnauthorizedAccessException)
        {
            return false;
        }
        return isInRoleWithAccess;
    }
Run Code Online (Sandbox Code Playgroud)


Ali*_*sad 6

以上解决方案很好,但对我来说,我发现这段代码简单可行。只需创建一个临时文件。如果创建了文件,则其平均用户具有写访问权限。

        public static bool HasWritePermission(string tempfilepath)
        {
            try
            {
                System.IO.File.Create(tempfilepath + "temp.txt").Close();
                System.IO.File.Delete(tempfilepath + "temp.txt");
            }
            catch (System.UnauthorizedAccessException ex)
            {

                return false;
            }

            return true;
        }
Run Code Online (Sandbox Code Playgroud)

  • 好的!但有一件事是该用户可能具有“创建”权限但没有“删除”权限,在这种情况下,即使用户 _does_ 具有写入权限,这也会返回 false。 (3认同)
  • 使用 `Path.Combine` 代替,例如 `Path.Combine(tempfilepath, "temp.txt")`。 (2认同)

Bru*_*eri 5

我使用相同的函数检查文件是否hasWriteAccess:

    private static bool HasWriteAccessToFile(string filePath)
    {
        try
        {
            // Attempt to get a list of security permissions from the file. 
            // This will raise an exception if the path is read only or do not have access to view the permissions. 
            File.GetAccessControl(filePath);
            return true;
        }
        catch (UnauthorizedAccessException)
        {
            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)