4

我在 .NET 3.5 中尝试FileIOPermission在 Windows 7 中使用。我曾经是 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确认权限被授予,但是在执行时File.Copy()我确实得到了异常。

虽然我很高兴看到 .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 => 允许

我使用 anEnum.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;
}
4

1 回答 1

5

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

-Oisin

于 2010-01-27T19:14:55.640 回答