问题:用户连接到计算机上的服务,例如 IIS 网站或 SQL Server 数据库。该站点或数据库需要访问网络资源,例如文件共享(最常见)或其他服务器上的数据库。权限被拒绝。
这是因为运行该服务的用户首先没有网络权限,或者如果有,也没有权限访问远程资源。
我一次又一次地遇到这个问题,并且厌倦了没有一个真正可靠的方法来处理它。
以下是我所知道的一些解决方法:
以被授予高权限的自定义域用户身份运行 IIS
如果每次只授予一个文件共享权限,那么每次我想从新共享读取数据时,我都必须请网络管理员帮我添加。最终,随着许多网站从多个共享读取数据,它将变得真的很复杂。如果权限被完全开放,以便用户访问我们域中的任何文件共享,那么这似乎是一个不必要的安全表面积。
这也适用于在 IIS 上运行的所有站点,而不仅仅是需要访问的选定站点或虚拟目录,这是进一步的表面积问题。
执行相同的操作,但使用应用程序池或单独设置凭据
不必以特定用户身份运行整个 IIS 实例:每个站点、应用程序和文件夹都可以设置为在特定应用程序池或手动选择的一组凭据下运行。这解决了一小部分表面区域问题,但并没有真正解决有关管理权限粒度和跨许多资源执行此操作的其他问题。
仍然使用 IUSR 帐户但赋予其网络权限并在远程资源上设置相同的用户名(不是域用户,而是本地用户)
这也存在一些问题。例如,我正在使用一个文件共享,我有完全的共享权限,但我无法登录到机器。所以我必须找到合适的管理员并请他帮我做这件事。任何时候需要更改某些内容,都需要向管理员提出另一个请求。
允许 IIS 用户以匿名方式连接,但将用于匿名访问的帐户设置为高权限帐户
这比赋予 IIS IUSR 完全权限更糟糕,因为这意味着我的网站首先不能使用任何类型的安全性。
使用 Kerberos 连接,然后委托
这在原则上听起来不错,但存在各种问题。首先,如果您使用的是虚拟网站,而您连接到网站的域名不是基本计算机名称(我们经常这样做),那么您必须使用 Microsoft 的 SetSPN 实用程序在 Web 服务器上设置服务主体名称。这很复杂,而且显然容易出错。此外,您必须要求您的网络/域管理员更改 Web 服务器和域帐户的安全策略,以便它们“被信任可以委派”。如果您没有完全正确完成所有操作,那么您预期的 Kerberos 身份验证就会突然变成 NTLM,您只能模拟而不是委派,因此无法以用户身份通过网络进行联系。此外,这种方法可能会有问题,因为有时您需要网站或数据库具有连接用户没有的权限。
创建一个服务或 COM+ 应用程序来获取网站资源
服务和 COM+ 包使用它们自己的一组凭据运行。以高权限用户身份运行是可以的,因为他们可以执行自己的安全措施并拒绝不合法的请求,将控制权交给应用程序开发人员而不是网络管理员。问题:我在 Windows Server 2000 上使用一个 COM+ 包来执行此操作,以将高度敏感的图像传送到安全的 Web 应用程序。我尝试将网站移动到 Windows Server 2003,但突然被拒绝实例化 COM+ 对象的权限,很可能是注册表权限。我搜索了好一会儿,并没有解决问题,部分原因是我不愿意授予 IUSR 帐户完全注册表权限。这似乎与以高权限用户身份运行 IIS 一样糟糕。
注意:这其实很简单。在您选择的编程语言中,您可以创建一个类,该类具有一个返回所需对象实例的函数(例如 ADODB.Connection),并构建一个 dll,将其注册为 COM+ 对象。在您的 Web 服务器端代码中,您可以创建该类的实例并使用该函数,由于它在不同的安全上下文中运行,因此对网络资源的调用可以正常工作。
将驱动器号映射到共享
理论上这可行,但在我看来,这并不是一个好的长期策略。尽管可以使用特定凭据创建映射,并且可以由网络管理员以外的其他人完成,但这也意味着要么有太多共享驱动器(小粒度),要么授予整个文件服务器太多权限(大粒度)。另外,我还没有弄清楚如何映射驱动器以便 IUSR 获取驱动器。映射驱动器是针对当前用户的,我不知道 IUSR 帐户密码,无法以该帐户身份登录并创建映射。
将本地资源移动到 Web 服务器/数据库
我有时也会这样做,尤其是使用 Access 数据库时。数据库是否有如何在文件共享中生存?有时,最简单的方法是将数据库移动到 Web 服务器或 SQL 数据库服务器(这样链接到它的服务器就可以工作)。但我也不认为这是一个很好的万能解决方案。当资源是服务而不是文件时,它不会起作用。
将服务移至最终的 Web 服务器/数据库
我想我可以在我的 SQL Server 数据库上运行一个 Web 服务器,这样网站就可以使用模拟连接到它,让我很开心。但我们真的想在我们的数据库服务器上随机添加额外的 Web 服务器来实现这一点吗?不。
IIS 中的虚拟目录
我知道虚拟目录可以帮助使远程资源看起来像是本地资源,并且它支持为每个虚拟目录使用自定义凭据。我还没有想出如何解决系统调用的问题。用户可以直接访问文件共享,但这对经典的 ASP 代码访问资源没有帮助。我可以使用 URL 而不是文件路径来读取网页中的远程数据文件,但这不会帮助我连接到 Access 数据库、SQL 服务器数据库或任何其他使用连接库的资源,而只能读取所有字节并使用它们。
我希望有某种可以创建的“服务隧道”。想想 VPN 如何使远程资源看起来像本地资源。有了更丰富的别名机制(可能是基于代码的),为什么甚至数据库连接都不能发生在定义的安全上下文中?为什么不使用特殊的 Windows 组件,让您为每个用户指定可用的资源以及用于连接的备用凭据?文件共享、数据库、网站,随便什么都可以。我想我几乎是在谈论一个专门的本地代理服务器。
不管怎样,这就是我的清单。如果我想到更多,我可能会更新它。有人能给我一些想法吗?
我目前的问题是,我又需要一个网站来连接到文件共享上的 Access 数据库。我们再来一次……
答案1
我个人建议通过身份验证和 .net 模拟,每个应用程序使用一个唯一的域帐户。就像您所说的那样,域管理员会遇到瓶颈,但每次更改访问权限都必须通过管理员,这实际上是一件好事。
大概一旦每个应用程序设置了共享(明确定义的设置过程的一部分?)它们就不会发生太大变化了?
管理员可以遵循明确定义的流程,包括记录访问权限以及管理层的签字授权。如果您恰好在监管环境中工作,那么一切都会保持良好和安全,并且非常有利于外部审计。
答案2
答案3
通过 SQL 复制/日志传送和/或文件同步使所有这些网络/远程资源本地化(Microsoft 的同步框架是一种选择,尽管在我看来,cygwin + rsync 的对称性更有吸引力)。
当然,所有这些都取决于数据变化的频率和/或是否需要双向同步或简单的镜像。
答案4
假设您没有从前端到后端共享通过身份验证的安全要求,我会研究如何让此应用程序需要访问的网络资源处于一个安全根之下。DFS 共享之类的东西可能非常适合这种情况。
其次,我会将安全性分配给 AD 安全组,而不是单个服务帐户或计算机。
从那里我可能会使用服务帐户和计算机名称,因为它们有意义。例如,您可能只将数据库服务器的服务帐户 (DOMAIN/MACHINENAME$) 添加到组中,但如果您有一组 Web 应用服务器,则可以使用通用服务帐户。