使用模仿器复制文件会抛出未经授权的访问异常

时间:2016-04-20 07:19:48

标签: c# impersonation networkcredentials

我正在使用this Impersonator class将文件复制到具有访问权限的目录。

public void CopyFile(string sourceFullFileName,string targetFullFileName)
{
    var fileInfo = new FileInfo(sourceFullFileName);

    try
    {
        using (new Impersonator("username", "domain", "pwd"))
        {
            // The following code is executed under the impersonated user.
            fileInfo.CopyTo(targetFullFileName, true);
        }
    }
    catch (IOException)
    {
        throw;
    }
}

这段代码几乎完美无缺。 我面临的问题是当sourceFullFileName是位于文件夹中的文件时,如 C:\ Users \ username \ Documents ,原始用户可以访问但不是模仿者。

尝试从此类位置复制文件时遇到的异常是:

  

mscorlib.dll中发生未处理的“System.UnauthorizedAccessException”类型异常   附加信息:拒绝访问路径“C:\ Users \ username \ Documents \ file.txt”。

2 个答案:

答案 0 :(得分:2)

在模拟之前,当前用户可以访问源文件路径,但不能访问目标文件路径。

模仿后,情况正好相反:模拟用户可以访问目标文件路径,但不能访问源文件路径。

如果文件不是太大,我的想法如下:

public void CopyFile(string sourceFilePath, string destinationFilePath)
{
    var content = File.ReadAllBytes(sourceFilePath);

    using (new Impersonator("username", "domain", "pwd"))
    {
        File.WriteAllBytes(destinationFilePath, content);
    }
}

即:

  1. 将源文件路径中的所有内容读入内存中的字节数组。
  2. 进行模仿。
  3. 将内存中字节数组中的所有内容写入目标文件路径。
  4. 此处使用的方法和类:

答案 1 :(得分:1)

感谢@Uwe Keim的想法,以下解决方案完美无缺:

    public void CopyFile(string sourceFullFileName,string targetFullFileName)
    {
        var fileInfo = new FileInfo(sourceFullFileName);

        using (MemoryStream ms = new MemoryStream())
        {
            using (var file = new FileStream(sourceFullFileName, FileMode.Open, FileAccess.Read))
            {
                 byte[] bytes = new byte[file.Length];
                 file.Read(bytes, 0, (int)file.Length);
                 ms.Write(bytes, 0, (int)file.Length);
             }

            using (new Impersonator("username", "domain", "pwd"))
            {
                 using (var file = new FileStream(targetFullFileName, FileMode.Create, FileAccess.Write))
                 {
                       byte[] bytes = new byte[ms.Length];
                       ms.Read(bytes, 0, (int)ms.Length);
                       file.Write(bytes, 0, bytes.Length);
                       ms.Close();
                 }
            }
        }
    }