问题:用户连接到机器上的服务,例如 IIS 网站或 SQL Server 数据库。站点或数据库需要访问网络资源,例如文件共享(最常见)或不同服务器上的数据库。权限被拒绝。
这是因为运行服务的用户首先没有网络权限,或者如果有,它没有访问远程资源的权限。
我一遍又一遍地遇到这个问题,并且厌倦了没有真正可靠的方法来处理它。
以下是我知道的一些解决方法:
作为被授予高权限的自定义域用户运行 IIS
如果一次授予一个文件共享的权限,那么每次我想从一个新的共享中读取时,我都必须让网络管理员为我添加它。最终,随着许多网站从许多共享中读取,它会变得非常复杂。如果只是为用户开放访问我们域中的任何文件共享的权限,那么这似乎是一个不必要的安全表面区域。
这也适用于在 IIS 上运行的所有站点,而不仅仅是需要访问的选定站点或虚拟目录,这是进一步的表面问题。
做同样的事情,但使用应用程序池或单独设置凭据
不必以特定用户身份运行整个 IIS 实例:可以将每个站点、应用程序和文件夹设置为在特定应用程序池或手动选择的一组凭据下运行。这解决了表面区域问题的一小部分,但并没有真正解决有关管理权限粒度和跨许多资源这样做的其他问题。
仍然使用IUSR帐户,但给它网络权限并在远程资源上设置相同的用户名(不是域用户,本地用户)
这也有它的问题。例如,我正在使用一个我拥有完全共享权限的文件共享,但我无法登录到机器。所以我必须找到合适的管理员并让他为我做这件事。任何时候必须更改某些内容,都是对管理员的另一个请求。
允许 IIS 用户以匿名身份连接,但将用于匿名访问的帐户设置为高权限帐户
这比给予 IIS IUSR 完全权限更糟糕,因为这意味着我的网站一开始就不能使用任何类型的安全性。
使用 Kerberos 连接,然后委托
这在原则上听起来不错,但有各种各样的问题。首先,如果您使用的是虚拟网站,而您连接到该网站的域名不是基本机器名称(正如我们经常做的那样),那么您必须使用 Microsoft 在网络服务器上设置服务主体名称SetSPN 实用程序。它很复杂,显然容易出错。此外,您必须要求您的网络/域管理员更改 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 数据库。我们重新来过吧...
我个人建议通过身份验证和 .net 模拟,对每个应用程序使用唯一的域帐户。就像您说的域管理员的瓶颈一样,但是访问权限的每次更改都必须通过管理员,这实际上是一件好事。
据推测,一旦为每个应用程序设置了共享(作为明确定义的设置过程的一部分?),它们真的不会有太大变化吗?
管理员可以有一个定义明确的流程来完成,其中包括访问授权的文档,以及来自管理层的签字授权。这样一来,如果您碰巧在监管环境中工作,一切都会保持良好和安全,并且对外部审计非常友好。
请参阅http://support.microsoft.com/kb/207671
通过 SQL 复制/日志传送和/或文件同步将所有这些网络/远程资源本地化(Microsoft 的 Sync Framework 是一个选项,尽管 cygwin + rsync 的简单性更具吸引力,IMO)。
当然,所有这些都取决于数据更改的频率和/或您是否需要双向同步或只是镜像。
如果您不想使用 Kerberos,您可以在访问资源时模拟用户,使用他们在使用基于表单的身份验证进行身份验证时创建的令牌。这应该使用 SSL 证书,至少在登录期间是这样。
假设您没有将身份验证从前端传递到后端共享的安全要求,我将研究如何获取此应用程序需要在一个安全根目录下访问的网络资源。像 DFS 共享这样的东西可能是完美的。
其次,我会将安全性分配给 AD 安全组,而不是单个服务帐户或计算机。
从那里我可能会使用服务帐户和计算机名称,因为它们是有意义的。例如,您可能只是将数据库服务器的服务帐户 (DOMAIN/MACHINENAME$) 添加到该组,但如果您有一个 Web 应用程序服务器集群,您将使用一个公共服务帐户。