BLUF
我们的应用程序正在尝试使用在.NET 4.5,IIS 7.5和Windows Server 2008 R2下运行的ASP.NET Web服务将文件写入UNC文件夹 . 但是,任何将文件写入所需位置的尝试都会导致访问被拒绝的异常 .
这项任务似乎很简单但是我和我的团队已经对此进行了一段时间的故障排除,我们对可能导致错误的原因感到困惑 . 以下是我们的设置细节以及到目前为止我们尝试过的内容 . 名称已被更改以保护无辜者 .
环境设置
Web服务器mywebserver有一个名为My.Site.Com的网站,其中包含一个名为My.Site.Com的相应应用程序池 . 应用程序池的配置如下所示 .
.NET Framework Version : v4.0
Enable 32-bit Applications : False
Managed Pipeline Mode : Integrated
Name : My.Site.Com
Identity : ApplicationPoolIdentity
Load User Profile : False
我们试图写入的UNC路径是\ myotherserver \ mydirectories \ output,其中mydirectories是实际共享 . 在此共享上,名为mygroup-www的域组已被授予对共享和所有子文件夹的完全权限 . 机器帐户(即mywebserver)是此mygroup-www组的成员 .
注意:目前,这个UNC路径实际上位于同一台机器mywebserver上 . 但是,在我们的测试环境中以及 生产环境 环境中,当它准备就绪时,最终会将其移动到mywebserver以外的机器上 . 目前,我只有一个测试环境来进行故障排除 .
可以通过执行以下代码来复制错误 .
[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public string ExportReport(int reportId)
{
try
{
string output = ConfigHelper.OutputPath + "test.html"; // UNC path
string url = ConfigHelper.VirtualPath + "test.html";
string[] lines = { "Hello", "World!" };
File.WriteAllLines(output, lines); // Access Denied!
return url;
}
catch (System.Exception ex)
{
Logger.ErrorException("Error exporting report", ex);
throw;
}
}
故障排除
尝试失败
我们在文件夹上尝试了各种组/用户权限组合(如下所示) . 运行这些测试时,我们还运行了Process Monitor . 对于每个配置,我们看到了相同的结果 . w3wp.exe进程尝试在所需位置创建文件,但报告了ACCESS DENIED的结果 . 每个配置的用户都是IIS APPPOOL \ My.Site.Com .
-
向\ myotherserver \ mydirectories授予mydomain \ mymachine $完全权限
-
授予\ myotherserver \ mydirectories \ output mydomain \ mymachine $完全权限
注意:我也尝试修改代码,以便从\ myotherserver \ mydirectories \ output中读取一个简单的文件 . 尝试读取文件时,进程失败并显示ACCESS DENIED消息,就像写入文件时一样 .
成功尝试
我们还尝试了几种有效的配置 .
授予本地IIS APPPOOL \ My.Site.Com权限
第一个配置是将IIS APPPOOL \ My.Site.Com的完全权限授予\ myotherserver \ mydirectories文件已成功写入,但进程's user was quite unexpectedly a domain account that was set up for a web application on the same machine in another website. This remains very confusing but worked as the ' other'帐户也具有对共享的写入权限 .
这在 生产环境 中不起作用,因为我们不能使用本地帐户来授予对网络资源的访问权限,但仍然是一个有趣的数据点 .
将应用程序池标识更改为域用户
第二个配置是将My.Site.Com应用程序池的标识更改为对\ myotherserver \ mydirectories具有完全权限的域帐户 . 这是一个由我们手动创建的'vanilla'域帐户 . 我们没有捕获过程的用户是什么,但可能是另一个有用的数据点 .
此选项可能是可行的,但是它会脱离IIS 7.5的最佳实践,并且由于相当严格的IT策略,可能不允许在我们的 生产环境 环境中使用 .
在我的开发机器上运行站点
第三个测试是在我的开发机器mydevmachine上本地运行该站点 . 我的本地IIS配置与mywebserver完全相同,但我运行的是Windows 7而不是Windows Server 2008.我将mydomain \ mydevmachine的完全权限授予\ myotherserver \ mydirectories并运行应用程序 . 该文件已成功编写 . 根据Process Monitor,进程的用户已正确设置为IIS APPPOOL \ My.Site.Com .
结论
我们希望使用mywebserver的机器帐户启用设计的写访问 . 我们已阅读ApplicationPoolIdentity user cannot modify files in shared folder in Windows Server 2008和Permissions for Shared Folder for IIS 7 Application Pool Identity Across Domain以及Application Pool Identities .
根据此信息,我们应该能够使用计算机帐户授予对网络资源(如UNC路径)的读写访问权限 . 实际上,当我从开发机器运行网站时,我可以以所需的方式执行此操作 .
想到了几个想法 . 也许测试Web服务器的计算机帐户有问题 . 或者也许“其他”软件以某种方式干扰了这个过程 .
有什么可能导致这个问题的想法?我们还应该做些什么来排除故障?
3 回答
重新启动'mywebserver' .
惊叹于现在神秘功能的ApplicationPoolIdentity .
安装MS HotFix KB2545850并在KB2672809中了解有关此错误的详细信息,其中还显示了重现和演示此明显随机问题的步骤 . 直接下载链接here .
推测为什么Microsoft在发布该修补程序后的3年内未能为此发布正常的Windows更新 . 虽然由于这个模糊的问题,人们仍然会继续闯入并拔掉头发 .
了解其他与MS共享并享受此礼物的人仍然继续给予:
IIS application using application pool identity loses primary token?
DirectoryServicesCOMException 80072020 From IIS 7.5 Site Running Under ApplicationPoolIdentity
ApplicationPoolIdentity cannot access network resources
ApplicationPoolIdentity IIS 7.5 to SQL Server 2008 R2 not working
Windows Authentication Failed when using application pool identity
IIS 7.5 stops using machine account to connect to network resource when using AppPoolIdentity
您的Windows 7开发机器可能工作正常,因为它比服务器更频繁地重新启动 . 恭喜您撰写了非常好的详细错误报告 . 我很少在这看到 .
我在ASP.NET应用程序中使用AppPoolIdentity访问网络共享时遇到类似问题(访问被拒绝) . 使用NetworkService帐户或其他域帐户工作但这些不是最佳解决方案 . 我几乎完成了你所做的所有测试,但终于发现了一些有用的东西 .
我发现在访问共享时没有使用网络服务帐户,就像你做的那样(我期望的是domain \ machine $ account)
这对我们有用:在IIS网站上,转到身份验证并将匿名身份验证项更改为“应用程序池标识” . 它默认设置为“IUSR” . 这解决了我们的问题 .
也许激活ASP.NET模拟(仍然在身份验证菜单中)可能会有所帮助 .
蒂博
我遇到了同样的问题,我通过为每个environemt(QA,STAGE,PRODUCTION)创建一个域帐户来解决 . 在应用程序池标识中,我已设置自定义帐户,我使用域用户作为各自的帐户 . 现在它让我能够从UNC Path写入和读取文件 .