如何正确设置IIS 7应用程序池标识?

将我的网站部署到IIS7.5后,我发现了一个奇怪的行为:默认情况下,当应用程序池标识为ApplicationPoolIdentity (如IIS应用程序池标识中所推荐的那样), Ninject似乎被忽略,因为我在创建时遇到以下错误第一个控制器:

System.InvalidOperationException:尝试创建类型为“..MainController”的控制器时发生错误。 确保控制器具有无参数的公共构造函数。 —> System.DirectoryServices.DirectoryServicesCOMException:发生操作错误。

我试图将IIS AppPool\ FullAccess授予包含该站点(包括所有子文件夹和文件)的文件夹,但这并没有改变任何内容。

但是,当我将应用程序池标识设置为任何域帐户(即使是简单的帐户,没有管理权限,以及没有对该站点的文件夹的任何访问权限)时,它仍然可以正常工作。

根据通过NuGet包设置MVC3应用程序教程安装Ninject。

我不确定,如果相关,该网站应该在具有Windows身份validation的域Intranet中工作。

因此,唯一的问题似乎是应用程序池标识。 至于我渴望使用推荐的方式,我希望拥有ApplicationPoolIdentity ,而不是域帐户。

这有什么用呢? 是否可以将所有这些混合在一起?


这是一个具有类似问题的SO线程: ASP.NET MVC 4 + Ninject MVC 3 =没有为此对象定义的无参数构造函数 。 但是根本没有合适的答案。


作为删除的评论建议,我尝试使用NetworkSerive作为身份。 它运作正常。 但是,我想这并不比非特权域帐户好多少。


编辑

突然发现另一个依赖:应用程序池标识用于sql server上的windows身份validation,但我希望在那里使用客户端用户的凭据。

根据评论

同意通过模拟可以使用经过身份validation的凭据访问远程SQL Server。


但是,仍然不清楚ApplicationPoolIdentity和Ninject的问题是什么。

在这个问题的最顶部提到的文章让我想到这可能是由于虚拟帐户没有用户配置文件这一事实造成的。 这个方面对我来说仍然不清楚,因为仍然可以使IIS使用LoadUserProfile属性加载用户配置文件。 如果虚拟帐户没有配置文件,我无法获取,IIS将加载什么?

有人说:

IIS不会加载Windows用户配置文件,但某些应用程序可能会利用它来存储临时数据。 SQL Express是执行此操作的应用程序的示例。 但是,必须创建用户配置文件以将临时数据存储在配置文件目录或注册表配置单元中。 NETWORKSERVICE帐户的用户配置文件由系统创建,始终可用。 但是,通过切换到唯一的应用程序池标识,系统不会创建任何用户配置文件。 只有标准应用程序池(DefaultAppPool和Classic .NET AppPool)在磁盘上具有用户配置文件。 如果管理员创建新的应用程序池,则不会创建用户配置文件。

但是,如果需要,可以通过将“LoadUserProfile”属性设置为“true”来配置IIS应用程序池以加载用户配置文件。


我在serverfault.com上找到了以下主题:

如何将活动目录权限分配给默认应用程序池标识

在那里还指出,应用程序池标识不能用作网络服务,特别是查询AD。

从问题中的细节来看,它听起来很像是一个导致抛出COMException的权限问题,这阻止了Ninject实例化MainController 。 该exception与System.DirectoryServices有关, System.DirectoryServices是用于查询Active Directory的类。

当IIS在正常的应用程序池帐户下运行时,这些帐户无权对Active Directory进行查询,并且可能抛出COMException 。 我认为exception中的实际消息(找不到无参数构造函数)有点像红色鲱鱼,并且Ninject试图回退到另一个构造函数,因为正常的消息不起作用。

这可以解释为什么当您更改IIS应用程序池以作为域帐户运行时,它突然起作用,因为该帐户确实有权查询域。

从您自己是否正在使用System.DirectoryServices或Ninject / IIS / ASP是否正在使用它们的问题中不清楚。 如果您自己使用它们,请确保AD类中的任何构造函数都不能抛出exception(捕获它们并记录它们或其他东西),这会阻止您的应用程序在启动时崩溃。 你可能会发现我上面说的关于权限的内容。

如果您需要IIS作为普通应用程序池帐户运行(这是一个好主意),但仍然将AD作为域用户进行查询,那么您可以指定DirectoryEntry的凭据并使用DirectorySearcher进行AD搜索。 如果您使用的是.Net 4或更高版本,那么我建议您使用新的System.DirectoryServices.AccountManagement类(这也允许您指定凭据)。

使用该方法,您不需要对AD查询进行任何模拟,您的应用程序池仍可以作为普通的应用程序池帐户运行。

iispool \ appPoolName帐户被称为虚拟帐户并被添加到Windows 2008.这个想法认为它们不是真正意义上的帐户。 他们允许的是使用基本帐户增强进程之间的安全性。

您计算机上的许多服务都使用networkService,这是一个具有网络访问权限的内置帐户。 因此,如果攻击者利用其中一种服务,则可以访问在同一帐户下运行的任何其他进程。 虚拟帐户(例如IIS使用的帐户)通过显示为不同的帐户来防止这种情况,同时仍然是同一个帐户 – 您的asp.net应用程序仍然在技术上作为网络服务运行并授予此帐户访问权限仍然可以工作的内容。 这也意味着如果您需要访问网络资源,iispool帐户将这样做,因为网络服务会使用计算机域帐户。

如果要访问远程sql server,则应添加此帐户以允许从Web服务器进行访问。 我不建议使用模拟,除非你真的需要查看用户在SQL服务器上的用户。 如果您将其关闭,您的应用安全性会更简单。

至于为什么你的注射不起作用,它可能是你的任何依赖失败。 如果controllerA注入了ClassB,而ClassB又注入了ClassC并且该类没有注入ClassD,那么整个链就会失败。 我已经发生了这种情况,并且需要一段时间才能意识到它是从我所看到的东西中删除的东西。