这是我一直在研究但无处可去的 IIS 7.5 和 ASP.NET 的问题。任何帮助将不胜感激。
我的问题是:在 IIS 7.5 中使用 ASP.NET,在完全信任的情况下,IIS 和/或操作系统如何允许 Web 应用程序写入像 C:\dump
这样的文件夹?为什么我不必为应用程序池用户(在本例中为 ApplicationPoolIdentity
)显式添加写访问权限?
我知道的就这么多:
在 IIS 7.5 中,应用程序池的默认标识是 ApplicationPoolIdentity。
ApplicationPoolIdentity 代表一个名为“IIS APPPOOL\AppPoolName”的Windows 用户帐户,它是在创建应用程序池时创建的,其中AppPoolName 是应用程序池的名称。
默认情况下,“IIS APPPOOL\AppPoolName”用户是 IIS_IUSRS 组的成员。
如果您在完全信任下运行,您的 Web 应用程序可以写入文件系统的许多区域(不包括 C:\Users、C:\Windows 等文件夹)。例如,您的应用程序将有权写入某些文件夹,例如 C:\dump。
默认情况下,IIS_IUSRS 组没有被授予对 C:\dump 的读取或写入访问权限(至少没有通过 Windows 资源管理器中的“安全”选项卡可见的访问权限)。
如果您拒绝对 IIS_IUSRS 的写入访问,则在尝试写入文件夹时会收到 SecurityException(如预期的那样)。
那么,考虑到所有这些,如何向“IIS APPPOOL\AppPoolName”用户授予写访问权限? w3wp.exe 进程以该用户身份运行,那么是什么允许该用户写入它似乎没有显式访问权限的文件夹?
请注意,我理解这可能是为了方便起见,因为如果您在完全信任下运行,授予用户访问它需要写入的每个文件夹的权限会很痛苦。如果您想限制此访问,您始终可以在中等信任下运行该应用程序。我有兴趣了解操作系统和/或 IIS 允许这些写入发生的方式,即使似乎没有明确授予文件系统访问权限。
ApplicationPoolIdentity
被分配了 Users
组和 IIS_IUSRS
组的成员资格。乍一看,这可能看起来有些令人担忧,但是 Users
组的 NTFS 权限有些有限。
例如,如果您尝试在 C:\Windows
文件夹中创建一个文件夹,那么您会发现您做不到。 ApplicationPoolIdentity
仍然需要能够从 Windows 系统文件夹中读取文件(否则工作进程将如何能够动态加载必要的 DLL)。
关于您对能够写入 c:\dump
文件夹的观察。如果您查看高级安全设置中的权限,您将看到以下内容:
https://i.stack.imgur.com/2UnXC.png
查看从 c:\
继承的特殊权限:
https://i.stack.imgur.com/ZLam7.png
这就是您网站的 ApplicationPoolIdentity
可以读取和写入该文件夹的原因。该权限是从 c:\
驱动器继承的。
在您可能有数百个站点的共享环境中,每个站点都有自己的应用程序池和应用程序池标识,您可以将站点文件夹存储在已删除 Users
组并设置权限的文件夹或卷中,这样只有管理员和 SYSTEM 帐户具有访问权限(具有继承)。
然后,您将单独分配每个 IIS AppPool\[name]
对其站点根文件夹所需的必要权限。
您还应确保您创建的用于存储潜在敏感文件或数据的任何文件夹都已删除 Users
组。您还应确保您安装的任何应用程序不会将敏感数据存储在其 c:\program files\[app name]
文件夹中,而是使用用户配置文件文件夹。
所以,是的,乍一看,ApplicationPoolIdentity
似乎拥有比它应有的更多权利,但实际上它没有比它的组成员资格规定更多的权利。
可以使用 SysInternals Process Explorer tool 检查 ApplicationPoolIdentity
的组成员身份。找到使用您感兴趣的应用程序池标识运行的工作进程(您必须将 User Name
列添加到要显示的列列表中:
https://i.stack.imgur.com/xUQcp.png
例如,我在这里有一个名为 900300
的池,其应用程序池标识为 IIS APPPOOL\900300
。右键单击进程的属性并选择我们看到的安全选项卡:
https://i.stack.imgur.com/D9Zqu.png
正如我们所见,IIS APPPOOL\900300
是 Users
组的成员。
右键单击文件夹。单击属性 单击安全选项卡。你会看到这样的东西:
https://i.stack.imgur.com/FlPIc.jpg
单击上方屏幕中的“编辑...”按钮。你会看到这样的东西:
https://i.stack.imgur.com/C58r1.jpg
单击上方屏幕中的“添加...”按钮。你会看到这样的东西:
https://i.stack.imgur.com/e5v38.jpg
单击上方屏幕中的“位置...”按钮。你会看到这样的东西。现在,转到此树结构的最顶部并选择您的计算机名称,然后单击确定。
https://i.stack.imgur.com/t8Fc9.jpg
现在输入“iis apppool\your_apppool_name”并单击“检查名称”按钮。如果 apppool 存在,您将在带有下划线的文本框中看到您的 apppool 名称。单击确定按钮。
https://i.stack.imgur.com/1oweH.jpg
选中/取消选中您需要授予该帐户的任何访问权限 单击“应用”按钮,然后单击“确定”。
IIs 中的每个应用程序池默认在 c:\users 下创建自己的具有完全读/写权限的安全用户文件夹。打开您的用户文件夹并查看那里有哪些应用程序池文件夹,右键单击并检查他们对分配的应用程序池虚拟帐户的权限。您应该会看到您的应用程序池帐户已添加,并为其根和子文件夹分配了读/写访问权限。
因此,这种类型的文件存储访问是自动完成的,您应该能够在应用程序池用户帐户文件夹中写入您喜欢的任何内容,而无需更改任何内容。这就是为每个应用程序池创建虚拟用户帐户的原因。
我尝试使用此方法修复对 IIS 网站的访问问题,该问题在事件日志 → Windows → 应用程序中显示为 like the following:
Log Name: Application Source: ASP.NET 4.0.30319.0 Date: 1/5/2012 4:12:33 PM Event ID: 1314 Task Category: Web Event Level: Information Keywords: Classic User: N/A Computer: SALTIIS01 Description: Event code: 4008 Event message: File authorization failed for the request. Event time: 1/5/2012 4:12:33 PM Event time (UTC): 1/6/2012 12:12:33 AM Event ID: 349fcb2ec3c24b16a862f6eb9b23dd6c Event sequence: 7 Event occurrence: 3 Event detail code: 0 Application information: Application domain: /LM/W3SVC/2/ROOT/Application/SNCDW-19-129702818025409890 Trust level: Full Application Virtual Path: /Application/SNCDW Application Path: D:\Sites\WCF\Application\SNCDW\ Machine name: SALTIIS01 Process information: Process ID: 1896 Process name: w3wp.exe Account name: iisservice Request information: Request URL: http://webservicestest/Application/SNCDW/PC.svc Request path: /Application/SNCDW/PC.svc User host address: 10.60.16.79 User: js3228 Is authenticated: True Authentication Type: Negotiate Thread account name: iisservice
最后我不得不让 Windows Everyone
组 read access to that folder 让它正常工作。