C # 사용자에게 폴더에 대한 쓰기 권한이 있는지 테스트

실제로 시도하기 전에 사용자가 폴더에 쓸 수 있는지 테스트해야합니다.

Directory.GetAccessControl () 메서드를 사용하여 폴더에 대한 보안 권한을 검색하려고 시도하는 다음 메서드 (C # 2.0)를 구현했습니다 .

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

내가 쓰기 액세스를 테스트하는 방법을 인터넷 검색 할 때 이와 같은 것은 나타나지 않았으며 실제로 Windows에서 권한을 테스트하는 것은 매우 복잡해 보였습니다. 나는 지나치게 단순화하고 있으며이 방법이 효과가있는 것처럼 보이지만이 방법이 강력하지 않다는 것에 우려하고 있습니다.

현재 사용자에게 쓰기 액세스 권한이 있는지 테스트하는 방법이 올바르게 작동합니까?



답변

이것이 C #에서 폴더 액세스를 확인하는 데 유효한 방법입니다. 예외 가 발생할 수있는 유일한 장소는 예외의 오버 헤드가 문제 있는 단단한 루프에서 이것을 호출 해야하는 경우 입니다.

이전 에 다른 비슷한 질문 이있었습니다 .


답변

이 게시물의 날짜가 약간 늦었지만 감사합니다.이 코드가 유용 할 수 있습니다.

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

콘솔 앱에 드롭하고 필요한 작업인지 확인하십시오.


답변

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

답변

나는 이것들의 대부분을 시도했지만 그것들은 같은 이유로 거짓 긍정을 준다. 사용 가능한 권한에 대해 디렉토리를 테스트하는 것만으로는 충분하지 않다. 허가. 이를 위해 사용자 ID를 확보하고 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;
    }

답변

IMHO 디렉토리에 쓸 수 있는지 테스트하는 유일한 100 % 신뢰할 수있는 방법은 실제로 디렉토리에 쓰고 결국 예외를 잡는 것입니다.


답변

예를 들어 모든 사용자 (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;
    }
}

답변

이 시도:

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