无法复制文件,即使在 C# 中授予了 FileIOPermission

Posted

技术标签:

【中文标题】无法复制文件,即使在 C# 中授予了 FileIOPermission【英文标题】:Cannot copy file, even though FileIOPermission is granted in C# 【发布时间】:2011-01-10 02:44:25 【问题描述】:

我在 .NET 3.5 的 Windows 7 中试用 FileIOPermission。我曾经是 Windows XP 用户,并且因为我是管理员而被授予此权限

我写了如下代码,测试看看能不能写到C:\Program Files\Outlook......

static void Main(string[] args)

    Console.WriteLine("Am I an administrator? " + new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

    //  Try and open a file in C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll
    string path = @"C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll";

    try
    
        FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
        ioPerm.Demand();

        string backupPath = Path.ChangeExtension(path, ".bak");
        FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
        writeAccess.Demand();

        Console.WriteLine("Read access is permitted: 0 => 1",path,SecurityManager.IsGranted(ioPerm));
        Console.WriteLine("Write backup file is permitted: 0 => 1", backupPath, SecurityManager.IsGranted(writeAccess));

        File.Copy(path, backupPath);

        Console.WriteLine("File copied! 0",backupPath);
        Console.WriteLine("Deleting file.....");
        File.Delete(path);
    
    catch (UnauthorizedAccessException uae)
    
        Console.WriteLine(uae.ToString());
    

    Console.ReadLine();

所以程序会导致UnauthorizedAccessException(这是我的预期),但我不明白的是Demand() 允许该权限,SecurityManager 确认该权限已被授予,但是在执行@987654326 时@我确实得到了例外。

虽然我很高兴看到 .NET 阻止了我,但为什么在我致电 Demand() 时它没有早点通知我?

我得到以下输出:

我是管理员吗?错误的 允许读取访问权限:C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll => True 允许写入备份文件:C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak => True System.UnauthorizedAccessException:对路径“C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak”的访问被拒绝。 在 System.IO.__Error.WinIOError(Int32 错误代码,字符串可能全路径) 在 System.IO.File.InternalCopy(字符串源文件名,字符串 destFileName,布尔覆盖) 在 System.IO.File.Copy(字符串源文件名,字符串 destFileName) 在 C:\Users\ 中的 TryAndGetUACPrompt.Program.Main(String[] args).......

请有人帮我理解为什么我会收到相互矛盾的信息?

--

更新 - 格林威治标准时间 19:30

我使用以下代码查看了源文件的 ACL:

Console.WriteLine("ACL Permissions for Source....");
FileSecurity fileSecurityForOriginalPath = new FileSecurity(path, AccessControlSections.Access);

foreach (FileSystemAccessRule rule in fileSecurityForOriginalPath.GetAccessRules(true,true,typeof(NTAccount)))

   Console.WriteLine("0 => 1", rule.FileSystemRights, rule.AccessControlType);

输出如下:

源的 ACL 权限...... 完全控制 => 允许 完全控制 => 允许 ReadAndExecute,同步 => 允许

因此,我确实有权阅读它。但是,我尝试使用此代码查看备份路径的权限,显然,由于我的备份(目标)文件实际上不存在,所以我无法检查权限就可以了。

接下来我将尝试另一个建议,将此检查转移到另一种方法中。

更新 - 格林威治标准时间 19:45

我已将读/写需求重构为另一种方法:

private static FileIOPermission CheckWriteAccess(string backupPath)

    FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
    writeAccess.Demand();
    return writeAccess;


private static FileIOPermission CheckReadAccess(string path)

    FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
    ioPerm.Demand();
    return ioPerm;

这些都返回正常,无一例外。

因此,如果 .NET 安全性增强了 DACL,我想知道为什么它认为它会成功,如果实际上并非如此。

--

格林威治标准时间 19:57 更新

好的,我检查了目录的权限,而不是备份文件(目标文件)并将其作为输出(使用来自 .GetAccessRules() 的 AuthorizationRuleCollection 上的 foreach)

正在检查此目录中的写入权限.... 完全控制 => 允许 268435456 => 允许 完全控制 => 允许 268435456 => 允许 完全控制 => 允许 268435456 => 允许 ReadAndExecute,同步 => 允许 -1610612736 => 允许 268435456 => 允许

我使用Enum.Format(typeof(FileSystemAccessRights),rule,"G") 来获取格式,有效地执行了 ToString(),但我只是不确定这些数字是否正确。

输出上述内容的代码:

private static DirectorySecurity CheckWriteAccess(string backupPath)

    DirectorySecurity writeAccess = new DirectorySecurity( Path.GetDirectoryName(backupPath),AccessControlSections.Access);

    Console.WriteLine("Checking write access in this directory....");
    foreach (FileSystemAccessRule rule in writeAccess.GetAccessRules(true, true, typeof(NTAccount)))
    
        Console.WriteLine("0 => 1", Enum.Format(typeof(FileSystemRights),rule.FileSystemRights,"G"), rule.AccessControlType);
    

    return writeAccess;

【问题讨论】:

阻止访问的不是 .NET 运行时,而是文件系统。 您只是在文件/文件夹的 ACL(访问控制列表)中枚举规则(访问控制条目/ACE),但您忽略了查看哪个 user 被授予哪个正确。例如,您显示“允许,允许”等,但您没有显示允许 。 ACL 中的每个 ACE 都描述了一个主体(用户或组)及其权限(r/w/x 等)。您还没有证明运行该程序的用户(您?)拥有对您尝试访问的资源具有完全控制权的 ACE。 哪个是最终解决方案的源代码示例? 解决方案是我的问题在于 Windows 安全性,而不是 .NET。 .NET 被授予对该文件的权限(未通过声明性安全性拒绝),但 Windows 没有。我希望这会有所帮助。 【参考方案1】:

读/写的 CAS IOPermisson 仅授予您读取或写入的能力。它不注意文件系统级权限 (ACL)。仔细检查文件夹上的 ACL :)

-奥辛

【讨论】:

也可能是你无法读取 DLL,因为它是由进程独占打开的。 我认为这会导致IOException 而不是UnauthorizedAccessException。 (不过,答案是 +1) 所以你的意思是.NET 在 CLR 中没有任何限制访问的用户限制,因此我被允许。但是..那么我必须直接询问文件系统,然后查看是否阻止它? @domnic - 是的。 CLR CAS 系统实现了所谓的“沙盒”。打个比方,它根据安全规则(证据)决定是否允许您尝试打开门(IOPermission)。但是,当您尝试打开门时,您会发现它已被锁定(ACL。)

以上是关于无法复制文件,即使在 C# 中授予了 FileIOPermission的主要内容,如果未能解决你的问题,请参考以下文章

即使 IAM 策略授予访问权限,Web 应用程序也无法访问私有 s3 文件

Flutter 应用程序无法在 apk-release 中运行,但可以在调试模式下运行(即使在授予 Internet 权限后)

Google Cloud Data Fusion 无法访问其他项目的数据,即使已授予访问权限

如何在c#中授予文件夹权限?

Postgres:即使授予了授权,也拒绝架构的权限

即使符号存在于 .so 文件中也无法加载符号? [复制]