【问题标题】:How to set up IIS 7 application pool identity correctly?如何正确设置 IIS 7 应用程序池标识?
【发布时间】:2013-03-18 14:45:03
【问题描述】:

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

System.InvalidOperationException:尝试执行时出错 创建一个类型的控制器 '..MainController'。确保 控制器有一个无参数的公共构造函数。 ---> System.DirectoryServices.DirectoryServicesCOMException:一个操作 发生错误。

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

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

按照Setting up an MVC3 application教程通过NuGet包安装Ninject。

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

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

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


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


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


编辑

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

基于 cmets

同意可以使用经过身份验证的凭据通过模拟访问远程 sql 服务器。


但仍不清楚 ApplicationPoolIdentity 和 Ninject 的问题所在。

这个问题开头提到的文章让我猜想这可能是由于虚拟帐户没有用户个人资料这一事实造成的。这方面对我来说仍然不清楚,因为仍然可以启用 IIS 来加载具有 LoadUserProfile 属性的用户配置文件。我不明白,如果没有虚拟帐户的配置文件,IIS 将加载什么?

据说:

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

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


我在 serverfault.com 上找到了以下帖子:

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

其中还指出,应用程序池身份无法作为网络服务工作,尤其是查询 AD。

【问题讨论】:

  • 您授予谁完全访问权限?
  • @V4Vendetta 我将FullAccess 授予IIS AppPool\<MySiteAppPool> 到包含该站点的文件夹(包括所有子目录和文件)
  • 好的,你有什么额外的东西出现在事件日志中吗?
  • 我的应用程序日志只获取上面发布的异常。正如 windows 日志一样,我在那里找不到任何合适的东西。
  • 您可以将应用程序池留给 ApplicationPoolIdentity,然后使用 asp 模拟以特定用户登录到您的数据库。查看身份验证部分,您会看到它。关键是您的 web.config 中的

标签: c# asp.net asp.net-mvc-3 iis-7 ninject


【解决方案1】:

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

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

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

至于为什么您的注入不起作用,可能是您的任何依赖项失败。如果 controllerA 被注入 ClassB,而 ClassB 又被注入 ClassC 并且该类未能注入 ClassD,那么整个链都会失败。我遇到过这种情况,过了一段时间才意识到它与我所看到的完全不同。

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 严格来说并非如此。网络服务是可以访问网络资源的低权限帐户。当它这样做时,它作为机器域帐户。因此,如果您要访问 AD 并且机器被称为 domain\webserver,它将使用凭据 domain\webserver$。但是,这些凭据的权限可能比您需要的要少。
    • @Simon 我已经更新了我的答案,以澄清 AD 查找不需要模拟,并删除了对 NetworkService 帐户的引用。这可能会产生误导,因为通常的 IIS 应用程序池帐户(例如 ASP.Net v4.0)和 NetworkService 帐户之间的差异,正如您所说,略有不同。
    • @AdamRodger 我认为您为我指明了正确的方向,因为我确实访问了 AD,这一定是在虚拟帐户下运行失败的原因。我会尽快检查。
    猜你喜欢
    • 1970-01-01
    • 2015-01-22
    • 2015-05-21
    • 2010-09-22
    • 2011-10-08
    • 1970-01-01
    • 2012-07-03
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多