我有一个网页,允许用户将文件上传到网络共享。当我在本地运行网页(在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();
}
}
对此的任何帮助都将非常感激!
答案 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服务器提供读/写访问权限。完成所有这些操作后,文件副本按预期工作。