C#Linq文件用户具有读取权限

时间:2011-09-22 03:00:22

标签: c# linq file-permissions acl

我如何在list.Items = directoryInfo.GetFiles("\\server\share\folder\");上使用Linq仅包含用户具有读取权限的文件?

... 到目前为止,只有建议使用try / catches或.NET 4.0中已过时的API?我更喜欢读取ACL的内容,看看特定用户或用户所属的组是否已被授予读访问权限。我正在尝试这样做,以便简化管理,向网站上的用户授予报告,这些网站的流量不会很高,因此“当您尝试打开文件时,谁知道您是否可以实际读取”的逻辑不会属于这种情况。我觉得微软真的应该让这项工作变得更容易。

4 个答案:

答案 0 :(得分:1)

试试这个。应该工作。虽然没有测试

  var fw = from f in new DirectoryInfo("C:\\Users\\User\\Downloads\\").GetFiles()
                where SecurityManager.IsGranted(new FileIOPermission
 (FileIOPermissionAccess.Write, f.FullName))
                select f;

编辑如果它只是只读文件,那么试试这个

var fe = from f in new DirectoryInfo("C:\\Users\\ashley\\Downloads\\").GetFiles()
                where f.IsReadOnly==true
                select f

答案 1 :(得分:1)

如果在打开文件之前检查读取权限,则存在竞争条件的风险。

如果您尝试阅读文件夹中有权访问的所有文件,最好只是尝试打开每个文件并抓住UnauthorizedAccessException

请参阅:

答案 2 :(得分:0)

注意:我没有测试过,但理论上它应该可以运行

首先,定义谓词以确定读取访问权限

bool CanRead(FileInfo file)
{
  try {
    file.GetAccessControl();
    //Read and write access;
    return true;
  }
  catch (UnauthorizedAccessException uae)
  {
    if (uae.Message.Contains("read-only"))
    {
      //read-only access
      return true;
    }
    return false;
  }
}

<小时/> 然后,应该是在linq查询

中使用where子句的简单情况
from file in directoryInfo.GetFiles("\\server\share\folder\") 
  where HaveAccess(f) == true
    select f;

答案 3 :(得分:0)

经过测试和工作,但如果文件正在使用中则返回false

void Main()
{
    var directoryInfo = new DirectoryInfo(@"C:\");
    var currentUser = WindowsIdentity.GetCurrent();
    var files = directoryInfo.GetFiles(".").Where(f => CanRead(currentUser, f.FullName));
}

private bool CanRead(WindowsIdentity user, string filePath)
{
    if(!File.Exists(filePath))
        return false;

    try
    {
        var fileSecurity = File.GetAccessControl(filePath, AccessControlSections.Access); 
        foreach(FileSystemAccessRule fsRule in fileSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
        {
            foreach(var usrGroup in user.Groups)
            {
                if(fsRule.IdentityReference.Value == usrGroup.Value)
                    return true;
            }
        }
    } catch (InvalidOperationException) {
        //File is in use
        return false;
    }

    return false;
}