【发布时间】:2014-04-10 00:44:07
【问题描述】:
蓝光
我们的应用程序正在尝试使用在 .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 当它准备好时。目前,我只有一个测试环境可以进行故障排除。
可以通过执行以下代码来复制错误。
[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。
- 授予 mydomain\mymachine$ 完全权限到 \myotherserver\mydirectories
- 授予 mydomain\mymachine$ 完全权限到 \myotherserver\mydirectories\output
注意:我也尝试过修改代码,使其读取 \myotherserver\mydirectories\output 中的简单文件。什么时候 试图读取文件,进程失败并显示访问被拒绝 写入文件时的消息。
成功尝试
我们还尝试了几种可行的配置。
授予本地 IIS APPPOOL\My.Site.Com 权限
第一个起作用的配置是授予 IIS APPPOOL\My.Site.Com 对 \myotherserver\mydirectories 的完全权限。文件已成功写入,但是进程的用户出乎意料的是,在另一个网站的同一台机器上为 Web 应用程序设置了一个域帐户。这仍然非常令人困惑,但因为“其他”帐户也具有共享的写入权限。
这在生产中不起作用,因为我们不能使用本地帐户来授予对网络资源的访问权限,但它仍然是一个有趣的数据点。
将应用程序池标识更改为域用户
第二个有效的配置是将 My.Site.Com 应用程序池的标识更改为对 \myotherserver\mydirectories 具有完全权限的域帐户。这是一个由我们手动创建的“普通”域帐户。我们没有捕捉到流程的用户是什么,但这可能是另一个有用的数据点。
此选项可能是可行的,但它脱离了 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 路径)的读写访问权限。事实上,在我的开发机器上运行网站时,我可以以所需的方式执行此操作。
我想到了几个想法。可能是测试网络服务器的机器账号有问题。或者也许那个“其他”软件以某种方式干扰了这个过程。
关于可能导致此问题的任何想法?我们还应该做些什么来解决问题?
【问题讨论】:
-
我假设如果您将池标识设置为
Networkservice它可以达到共享?这将排除 machineaccount$ 的任何问题。接下来,您能否删除共享上的“其他”域帐户的权限,看看您的第一个成功方案是否仍然有效?我怀疑虚拟池帐户在服务器上处于某种强化配置中,从而阻止它到达外部。这可以解释为什么您的开发机器可以工作。您现在可以通过尝试读取文件来简化测试。 -
我遇到了完全相同的问题。来自@AmitNaidu 的问题+1 和+1 表单评论我在我的身上尝试过,并且确实使用 NetworkService 我可以达到共享。但是,我们如何将 App Pool Identity 更改为没有“强化配置”? OP,你有没有让这个工作?
-
@akousmata,这只是我的第一个猜测,因为我看到了一些可能会干扰网络访问的限制性 GPO。但我不再认为那是 OP 的问题。他的症状与我在回答中描述的错误非常吻合。你已经消除了这种可能性吗?只需重新启动 IIS 服务器即可轻松验证。如果是这样,那么您将需要使用 procmon 进一步挖掘。您的配置也可能与 OP 不同,例如他没有使用假冒,你可能会。
-
@akousmata,不幸的是,我无法确定我的特定情况是由 Amit 描述的问题引起的,因为我们的环境已刷新并且问题不再出现。即便如此,我怀疑我们的问题是阿米特的回答中描述的问题。或者我们环境中的一些不稳定的网络问题确实会导致一些看似随机的身份验证问题(在我们的环境中并非闻所未闻)。
-
重启服务器修复了它。如果我们再次看到它,将应用此修补程序。
标签: permissions iis-7.5 access-denied