无法复制文件,即使在 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 权限后)