.NET模拟和文件上载问题

时间:2010-03-30 18:11:30

标签: .net file-upload impersonation

我有一个网页,允许用户将文件上传到网络共享。当我在本地运行网页(在VS 2008中)并尝试上传文件时,可以正常运行!但是,当我将网站部署到网络服务器并尝试通过网页上传文件时,它无法正常工作

在网络服务器上返回给我的错误说“拒绝访问路径'\ 05prd1 \ emp \ test.txt'。显然,这是权限问题。

网络共享配置为允许对我(NT身份验证)和NETWORK SERVICE(这是.NET的默认帐户以及我们在IIS应用程序池中设置的作为此网站的默认用户)的完全访问权限。

我在网络服务器上尝试了这个,没有模仿,但两种方式都不起作用,然后两种方式都可以在我的本地计算机上运行(换句话说,在我的本地计算机上有和没有模拟工作)。

执行文件上传的代码如下。请注意,下面的代码包括假冒,但就像我上面所说的那样,我已经尝试了它,没有假冒,它没有任何区别。

if (fuCourses.PostedFile != null && fuCourses.PostedFile.ContentLength > 0) {
    System.Security.Principal.WindowsImpersonationContext impCtx;
    impCtx =
        ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

    try {
        lblMsg.Visible = true;

        // The courses file to be uploaded
        HttpPostedFile file = fuCourses.PostedFile;
        string fName = file.FileName;
        string uploadPath = "\\\\05prd1\\emp\\";

        // Get the file name
        if (fName.Contains("\\")) {
            fName = fName.Substring(
                fName.LastIndexOf("\\") + 1);
        }

        // Delete the courses file if it is already on \\05prd1\emp
        FileInfo fi = new FileInfo(uploadPath + fName);
        if (fi != null && fi.Exists) {
            fi.Delete();
        }

        // Open new file stream on \\05prd1\emp and read bytes into it from file upload
        FileStream fs = File.Create(uploadPath + fName, file.ContentLength);

        using (Stream stream = file.InputStream) {
            byte[] b = new byte[4096];
            int read;

            while ((read = stream.Read(b, 0, b.Length)) > 0) {
                fs.Write(b, 0, read);
            }
        }

        fs.Close();

        lblMsg.Text = "File Successfully Uploaded";
        lblMsg.ForeColor = System.Drawing.Color.Green;
    }
    catch (Exception ex) {
        lblMsg.Text = ex.Message;
        lblMsg.ForeColor = System.Drawing.Color.Red;
    }
    finally {
        impCtx.Undo();
    }
}

对此的任何帮助都将非常感激!

2 个答案:

答案 0 :(得分:1)

您没有提到您在IIS中使用的身份验证类型。

如果您依赖Windows Integrated / NTLM身份验证,那么我认为您将遇到问题,除非您可以在服务器上配置Kerberos,否则用户的身份验证令牌不能在当前(Web)服务器之外使用 - “double-hop”问题。

如果您使用Basic(在IIS中)或Forms(通过ASP.NET),那么您将以明文形式访问用户的密码。然后,您可以使用用户名/密码调用模拟代码,并且应该能够以该用户身份访问共享文件夹。

我也很确定如果您使用基本身份验证,那么< identity impersonate =“true”> tag可用于网络共享访问。

查看KB 306158以获取更多信息和代码示例。

答案 1 :(得分:1)

问题在于Kerberos未从Web服务器委托给文件服务器。理想的解决方案是将Kerberos委派给文件服务器。不幸的是,这不是我有能力改变的东西。繁琐的繁文缛节和太多的政治因素。但是,我想出了各种各样的黑客。

我创建了一个位于网站根目录的临时文件夹。使用模拟,我将文件写入此临时文件夹(换句话说,它会上传到此临时文件夹)。

将文件写入临时文件夹后,我文件复制到文件服务器UNC。这是第二跳,这是我是否使用模拟没有区别 - 因为发送到文件服务器的凭据是Web服务器本身的凭据。因此,这迫使我做的是给UNC共享上的Web服务器提供读/写访问权限。完成所有这些操作后,文件副本按预期工作。