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

hor*_*rgh 9 c# asp.net iis-7 ninject asp.net-mvc-3

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

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

我试图授予FullAccessIIS AppPool\<MySiteAppPool>文件夹,包含该网站(包括所有子文件夹和文件),但这并没有改变任何东西.

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

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

我不确定,如果它是相关的,该站点应该在具有Windows身份验证的域Intranet中工作.

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

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


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


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


编辑

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

根据评论

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


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

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

有人说:

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

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


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

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

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

Sim*_*sey 9

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

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

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

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


Ada*_*ger 2

从问题的细节来看,这听起来很像导致COMException抛出 a 的权限问题,这导致 Ninject 无法实例化MainController。例外与System.DirectoryServices用于查询 Active Directory 的类有关。

当 IIS 在普通应用程序池帐户下运行时,这些帐户没有权限对 Active Directory 进行查询,并且可能COMException会引发错误。我认为异常中的实际消息(找不到无参数构造函数)有点转移注意力,并且 Ninject 试图回退到另一个构造函数,因为正常的构造函数不起作用。

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

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

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

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