2013-03-28 89 views
8

将我的网站部署到IIS7.5后,我发现了一个奇怪的行为:默认情况下应用程序池标识为ApplicationPoolIdentityIIS Application Pool Identities中推荐)时,Ninject似乎被忽略,因为出现以下错误创建第一个控制器:如何正确设置IIS 7应用程序池标识?

System.InvalidOperationException:试图 当创建 类型的控制装置发生了错误“..MainController”。确保 控制器有一个无参数的公共构造函数。 ---> System.DirectoryServices.DirectoryServicesCOMException:发生操作 错误。

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

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

Ninject根据Setting up an MVC3 application教程通过NuGet包安装。

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

所以,唯一的问题似乎与应用程序池的身份。据我急于使用推荐的方式,我喜欢有ApplicationPoolIdentity,而不是一个域帐户。

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


下面是一个SO有类似的问题线程:ASP.NET MVC 4 + Ninject MVC 3 = No parameterless constructor defined for this object。然而,在那里也没有合适的答案。


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


编辑

突然发现另一相关性:应用程序池标识用于SQL Server上的Windows身份验证,但笔者预计客户端用户的凭据并在那里使用。

基于评论

同意,远程SQL Server可以通过模拟的验证的凭据访问。


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

在这个问题的最顶端文章mentiond让我想,这可能由以下事实造成的,即虚拟账户没有用户配置文件。这方面仍然不清楚,因为我们仍然可以启用IIS来加载具有LoadUserProfile属性的用户配置文件。我无法得到,如果虚拟帐户没有配置文件,IIS将加载什么?

它的存在表示:

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

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


我发现下面的线程上serverfault.com:

How can I assign active directory permission to the default app pool identity

在那里,它也指出,应用程序池的身份是不能作为网络服务工作,特别是查询AD。

+0

您授予完全访问权限给谁? – V4Vendetta 2013-03-28 08:32:53

+0

@ V4Vendetta我将'FullAccess'授予'IIS AppPool \ '到包含该站点的文件夹(包括所有子目录和文件) – horgh 2013-03-28 08:35:15

+0

好吧,你有什么额外的事件日志显示吗? – V4Vendetta 2013-03-28 08:48:02

回答

2

从问题中的详细信息,它听起来很像权限问题,导致COMException被抛出,这阻止Ninject实例化MainController。异常与System.DirectoryServices有关,这些类别是用于查询Active Directory的类。

当IIS在正常应用程序池帐户下运行时,这些帐户没有权限对Active Directory进行查询,并且可以引发COMException。我认为,在异常(不能找到一个参数的构造函数),实际的消息是有点红鲱鱼的,是Ninject试图回落到另一个构造,因为正常的一个没有工作。

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

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

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

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

+0

这不完全正确。网络服务是可以访问网络资源的低权限帐户。当它这样做的时候,它就像机器域账号一样。因此,如果您要访问AD,并且该机器名为domain \ webserver,则它将使用凭据域\ webserver $。但是,这些凭据可能拥有的权限比您需要的少。 – 2013-04-05 23:53:06

+1

@Simon我已经更新了我的答案,以澄清AD模型不需要进行AD查找并删除了对NetworkService帐户的引用。由于通常的IIS应用程序池帐户(如ASP.Net v4.0)和NetworkService帐户(如您所说的)略有不同,这可能会产生误导。 – 2013-04-06 12:32:00

+0

@AdamRodger我认为你已经指出我正确的方向,因为我确实访问AD,这一定是在虚拟帐户下运行失败的原因。我会尽快检查一切。 – horgh 2013-04-08 00:39:10

9

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

您的机器上的许多服务使用networkService,这是一个内置的网络访问帐户。因此,如果攻击者利用这些服务之一,则可以访问在同一帐户下运行的任何其他进程。虚拟帐户(如IIS使用的虚拟帐户)通过显示为不同的帐户来防止这种情况发生,同时仍然是同一帐户 - 您的asp.net应用程序仍然在技术上运行,因为网络服务&授予此帐户访问权仍然有效。这也意味着如果您需要访问网络资源,则iispool帐户将这样做,因为networkservice确实使用了机器域帐户&。

如果您正在访问远程SQL服务器,这是您应该添加以允许从您的Web服务器访问的帐户。我不会建议使用模拟,除非您确实需要查看用户在SQL服务器上的用户。如果你离开它,你的应用程序安全性更简单。

至于为什么你的注射不起作用,它可能是你的任何依赖失败。如果控制器A注入ClassB,而ClassB又注入ClassC &该类未能注入ClassD,则整个链失败。我曾经遇到过这种情况,我花了一段时间才意识到这是从我看到的东西中删除的东西。