14

有什么方法可以让 IIS 无需使用NT SERVICE\NETWORK SERVICE用户帐户即可连接到 LocalDB。

此帐户没有合适的权限。我正在寻找使用其他默认帐户,或者有什么方法可以在NETWORK SERVICE不更改权限的情况下使用该帐户?

4

3 回答 3

19

您应该使用 LocalDB 的共享实例功能。这两篇关于将 LocalDB 与完整 IIS 结合使用的文章应该为您提供更多信息。特别是第二部分似乎相关,但第一部分也包含一些上下文。

(注意:原始链接不再可用,请改用archive.org)

  1. 第 1 部分:用户资料
  2. 第 2 部分:实例所有权

原始(截至 2019 年 3 月无效)链接:

  1. 第 1 部分:用户资料
  2. 第 2 部分:实例所有权
于 2012-11-09T17:43:50.480 回答
3

如果链接再次消失,我将从文章中复制粘贴解决方案以便于访问:

帖子 1:

我们面临的问题是需要加载用户配置文件。这应该不难,因为每个 IIS 应用程序池都有一个名为“加载用户配置文件”的选项,可以在“高级设置”部分找到。不幸的是,Windows 7 的 Service Pack 1 中的情况稍微复杂了一些。如 KB 2547655 中所述,启用loadUserProfile不足以完全加载用户配置文件,我们还需要启用setProfileEnvironment。这需要编辑applicationHost.config文件,该文件通常位于 C:\Windows\System32\inetsrv\config。按照 KB 2547655 中的说明,我们应该为应用程序池 ASP.NET v4.0 启用这两个标志,如下所示:

<add name="ASP.NET v4.0" autoStart="true" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated">
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</add>

完成后,我们重新启动应用程序池以确保应用新设置并再次运行我们的 Web 应用程序。

我这边的注意事项: 只需在该 applicationHost 文件中找到“applicationPools”标签并将这两个变量更新为 true,它看起来像这样:

<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />

就是这样,保存文件并重新启动 IIS 池。

帖子 2:

私有实例的问题

如我们所见,我们面临以下错误:

System.Data.SqlClient.SqlException: Cannot open database "OldFashionedDB" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.

这一次错误很明显。LocalDB 已启动并且 Web 应用程序能够连接到它,但连接随后由于登录失败而终止。IIS 应用程序池的 ApplicationPoolIdentity 帐户(在本例中为IIS APPPOOL\ASP.NET v4.0)无法登录到 LocalDB 实例,因为未找到连接字符串 ( OldFashionedDB ) 中指定的数据库。多么奇怪,因为使用相同的连接字符串从 Visual Studio 连接成功!

Visual Studio 怎么可能很好地连接到 LocalDB,而来自 Web 应用程序的连接失败?在这两种情况下,连接字符串如下:

Data Source=(localdb)\v11.0;Initial Catalog=OldFashionedDB;Integrated Security=True

答案是这里有两个不同的 LocalDB 实例。与作为 Windows 服务运行的 SQL Server Express 实例不同,LocalDB 实例作为用户进程运行。当不同的 Windows 用户连接到 LocalDB 时,他们最终会为每个用户启动不同的 LocalDB 进程。当我们连接到(localdb)\v11.0从 Visual Studio 中,为我们启动了一个 LocalDB 实例并作为我们的 Windows 帐户运行。但是,当在 IIS 中作为 ApplicationPoolIdentity 运行的 Web 应用程序连接到 LocalDB 时,会为其启动另一个 LocalDB 实例并作为 ApplicationPoolIdentity 运行!实际上,即使 Visual Studio 和 Web 应用程序都使用相同的 LocalDB 连接字符串,它们也会连接到不同的 LocalDB 实例。显然,在我们的 LocalDB 实例上从 Visual Studio 创建的数据库在 Web 应用程序的 LocalDB 实例中将不可用。

一个很好的类比是Windows 中的My Documents文件夹。假设我们打开 Visual Studio 并在我的文档文件夹中创建一个文件。然后我们以不同的用户身份登录到同一台机器并再次转到我的文档文件夹。我们不会在那里找到该文件,因为第二个用户的我的文档和我们的我的文档是两个不同的文件夹。同样,由两个不同用户拥有的 LocalDB 实例(localdb)\v11.0是具有两组不同数据库的两个不同进程。

这也是 Web 应用程序能够从 IIS Express 连接到 LocalDB 的原因。就像 LocalDB 一样,IIS Express 是一个用户进程。它由 Visual Studio 启动,并以与 Visual Studio 进程相同的 Windows 帐户运行。连接到(localdb)\v11.0的两个不同进程以同一个 Windows 帐户运行(Visual Studio 和 IIS Express,都作为我们的 Windows 帐户运行)正在连接到同一个 LocalDB 进程,也以同一个 Windows 帐户启动。

可能的解决方案

了解问题的本质带来了多种解决问题的方法。由于不同的方法有不同的权衡,而不是规定一种解决方案,下面我介绍了三种对我来说似乎最可行的方法。我希望听到你关于最适合你的那个!这是列表:

方法 1:以我们的 Windows 用户身份运行 IIS
方法 2:使用 LocalDB 共享实例
方法 3:使用完整的 SQL Server Express

让我们仔细看看它们中的每一个。

方法 1:以我们的 Windows 用户身份运行 IIS

如果不同的用户帐户是问题所在,为什么不尝试在我们的 Windows 帐户下运行我们的 Web 应用程序呢?Web 应用程序将连接到与 Visual Studio 相同的 LocalDB,一切都应该正常工作。

进行配置更改相对容易,只需启动 IIS 管理器并找到正确的应用程序池:

打开高级设置屏幕(在上下文菜单中可用):

单击Identity属性中的小按钮以显示Application Pool Identity屏幕:

再次启动 Web 应用程序将确认问题已解决:

这种方法的缺点是什么?当然,在我们的账户下运行 Web 应用程序会带来一定的安全风险。如果有人劫持了我们的 Web 应用程序,他们将能够访问我们帐户可以访问的所有系统资源。将 Web 应用程序作为 ApplicationPoolIdentity 运行可提供额外的保护,因为 ApplicationPoolIdentity 帐户对本地系统资源的访问权限非常有限。因此,我一般不能推荐这种方法,但如果小心使用,在某些情况下它是一个可行的选择。

方法二:使用 LocalDB 共享实例

我们还可以使用 LocalDB 的实例共享功能。它允许我们与同一台机器上的其他用户共享一个 LocalDB 实例。共享实例将以公共名称访问。

共享实例的最简单方法是使用 SqlLocalDB.exe 实用程序。只需启动管理命令行提示符,然后键入以下命令:

sqllocaldb share v11.0 IIS_DB

它将以公共名称 IIS_DB 共享私有 LocalDB 实例 v11.0。机器上的所有用户都可以使用 (localdb).\IIS_DB 作为服务器地址连接到该实例。注意 . 在实例名称之前,表示这是一个共享实例名称。我们应该用更新的连接字符串替换我们的 Web 应用程序中的连接字符串:

Data Source=(localdb)\.\IIS_DB;Initial Catalog=OldFashionedDB;Integrated Security=True

在 Web 应用程序可以使用共享实例之前,我们需要启动它并为 ApplicationPoolIdentity 创建登录名。启动实例很容易,只需从 SQL Server 对象资源管理器连接到它即可启动它并使其保持活动状态。进入 SQL Server 对象资源管理器后,我们还可以为 ApplicationPoolIdentity 创建登录。我们可以使用以下查询:

create login [IIS APPPOOL\ASP.NET v4.0] from windows;
exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin

此脚本为 ApplicationPoolIdentity 帐户提供对 LocalDB 实例的完全管理访问权限。只要有可能,我建议使用更有限的数据库级甚至表级权限。

现在我们可以再次运行我们的 Web 应用程序。这次它应该可以正常工作:

这种方法的缺点是什么?主要的一点是,在 Web 应用程序可以连接到共享实例之前,我们需要确保该实例已启动。为此,拥有该实例的 Windows 帐户必须连接到它,并且连接必须保持打开状态,否则 LocalDB 实例将关闭。

方法 3:使用完整的 SQL Server Express

由于完整的 IIS 作为服务运行,也许使用传统的、基于服务的 SQL Server Express 是正确的方法?我们可以只安装 SQL Server 2012 Express RC0 并在其中创建 OldFashionedDB 数据库。我们甚至可以使用我们全新的 SQL Server Data Tools 来执行此操作,因为它适用于任何 SQL Server 版本和版本。我们的连接字符串必须更改为:

Data Source=.\SQLEXPRESS;Initial Catalog=OldFashionedDB;Integrated Security=True

当然,就像前面的例子一样,我们需要确保 ApplicationPoolIdentity 帐户可以访问我们的 SQL Server Express 实例。我们可以使用与之前相同的脚本:

create login [IIS APPPOOL\ASP.NET v4.0] from windows;
exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin

之后,运行我们的 Web 应用程序再次带来快乐的画面:

这种方法的缺点是什么?显然我们失去了使用 LocalDB 的好处。安装 SQL Server Express 可能需要比 LocalDB 更多的时间,并且可能需要进行一些机器清理才能使其成功。SQL Server Express 安装程序可能会被损坏的 WMI 数据库、污染的注册表或 SQL Server 或 Visual Studio CTP 和 Beta 留下的组件等问题阻止。即使不需要 SQL Server Express,SQL Server Express 也会继续在后台运行,就像服务一样。

其他选项

还有其他在完整 IIS 下使用 LocalDB 的方法,此处未介绍。我们可以使用 Web 应用程序的私有 LocalDB 实例,并通过从 ASP.NET 代码执行 T-SQL 脚本通过 Web 应用程序与它进行通信。我们还可以使用 ADO.NET 连接字符串的 AttachDbFileName 选项,并使用一个数据库文件 (.mdf),该文件将在开发期间附加到我们的 LocalDB 和 Web 应用程序的 LocalDB 以进行调试。我都试过了,我发现它们太麻烦了,无法进一步讨论。

于 2021-02-26T15:58:15.103 回答
0

基于@KrzysztofKozielczyk 的回答。

我最初在这里发布了一个答案:

https://stackoverflow.com/a/62810876/3850405

在遵循此之后,我验证Load User Profile了 my 设置为 true Application Pool,然后设置setProfileEnvironmenttruein applicationHost.config。我通过applicationHost.config位于以下位置的编辑完成了最后一部分:

C:\Windows\System32\inetsrv\config\applicationHost.config

在此处输入图像描述

于 2021-05-12T07:35:18.487 回答