执行访问另一个SQL实例的存储过程


8

如果这个问题重复另一个已经提出的问题,我深表歉意。我搜索了几个小时,却没有找到适合我的情况。

期望的结果

使用SQL身份验证的用户具有Server1(默认实例)上的Database1的执行权限。用户执行存储过程,作为其过程的一部分,访问存储在Server1 \ Instance2上的数据库2。我希望它既安全又简单(两者都很重要)。

更多信息

我的Windows凭据可以访问两个实例(位于同一服务器上)。因此,我可以在登录时轻松执行存储过程。但是,我不想给用户我的访问权限。我还需要使用SQL登录名,因为该用户将不在域中。

我想要的是为存储过程提供仅针对该过程的访问级别。由于我是系统管理员,因此将为用户提供该过程所需的一切。如果我能做到这一点,我可能会为此目的创建一个帐户,而不是使用我的帐户,但是无论哪种方式都是安全的,因为我可以控制存储的proc的工作。

我尝试将“ WITH EXECUTE AS”语句放入存储的proc中,但无法获取Windows登录信息。当我将其放入时,编译存储的proc时会出现以下错误:

无法以用户“ domain \ jdoe”的身份执行,因为它不存在或您没有权限。

就像我说的,用户在两台服务器上都是sysadmin,所以我不确定它还需要什么。

我研究了以下内容:

  • 可信任-我宁愿不公开我的数据库,这看起来很可怕
  • 链接服务器-我不想授予额外的权限。我不信任其他数据库可以访问我的数据库,也不信任我的数据库可以访问所有其他数据库。
  • 证书-这似乎很复杂而且很困难。除非我能找到一种非常简单的方法来做到这一点并加以维护,否则我不确定这样做是否值得。
  • 所有权链接-再次令人恐惧。当我的目标是防止安全问题时,这似乎会引起更多的安全问题。
  • 镜像用户-我什至在另一个服务器实例上创建了相同(显然是不同的SID)用户,并给了它相同的密码。不行

我觉得自己缺少明显的东西,但不确定是什么。由于我整天都在用头撞墙,所以我可能太近了以至于看不到它。如果有人可以帮我或指出正确的方向,我将不胜感激。我会说我已经阅读了很多MSDN文章(男孩,我讨厌他们-他们似乎从来没有告诉我我想知道什么)。我真正想要的是一个简单易学的教程,它将指导我如何进行操作。缺少这一点,即使是一般性的指示我需要走的方向也会有所帮助。

Answers:


3

尝试改用EXECUTE AS LOGIN ='DOMAIN \ username',看看是否可行。


我试过了,但是显然该命令不是为存储过程内部设计的。
IAmTimCorey 2012年

它在存储过程中应该可以正常工作。您的帐户是否创建了自己的登录名,或者您是通过组成员身份获得权限的?
mrdenny 2012年

我的帐户具有自己的登录名,该登录名具有sysadmin权限。它还具有通过组成员身份的Domain Admin权限,因此应该可以给我我需要的一切,并且在使用Windows凭据登录时也可以实现。但是,我发现了两件事。首先,如果我在存储的proc的WITH语句中使用了您的上述代码,则会给我带来语法错误。如果我将其放在语句中,它将在一个实例内运行,但不能跨实例运行。
IAmTimCorey 2012年

3

看一下使用EXECUTE AS+ Trustworthy。您可以设置它在存储过程中可以在其中调用的位置,只要已授予用户b访问权限并且两个数据库相互信任即可。

这家伙博客应该回答或提供您需要的一切。 http://www.sommarskog.se/grantperm.html#EXECAScrossdb

使用TRUSTWORTHY数据库属性来控制对源数据库范围之外的资源的访问

http://msdn.microsoft.com/zh-cn/library/ms188304%28v=sql.90%29.aspx


我看到的问题是Trustworthy在两个数据库之间建立了信任关系。双方的系统管理员都可以利用此漏洞。我不要这个 我试图限制一个人的权限。如果我最终给另一个人更多的权限,那将不是一件好事。不过谢谢
IAmTimCorey'2

请注意,这里的个人所有者不必一定是自然人,但是它可以是每个数据库的通用登录名。您不必授予整个数据库的权限。如果您不信任其他数据库上的系统管理员,请坚持使用证书签名。
SoftwareCarpenter'2

您提到您在下面的答案中遇到了链接sommarskog.se/grantperm.html。那是我在建议的答案中张贴的同一博客。“这家伙的博客应该回答或提供您所需要的一切。sommarskog.se/grantperm.html#EXECAScrossdb “也许您只是在重新引用其他人。我同意这是一个不错的博客,值得阅读。祝好运!
SoftwareCarpenter'2

是的,很抱歉我忘了说链接来自你。这是一个很好的资源。谢谢你的帮助。
IAmTimCorey

2

在广泛阅读了该主题并进行了一些实验之后,我相信我已经就此问题得出了结论。EXECUTE AS语句并非旨在在没有重大安全隐患的情况下跨实例工作。我希望的是一种方法来告诉我的程序我想在哪个Windows身份下运行,因为Windows身份可以访问多个服务器上的多个资源。但是,即使在玩了很多不同的设置之后,很明显,我也不得不削弱其他安全措施,以允许存储过程模拟我。

似乎没有太多关于跨实例或跨服务器过程的信息。我可以想象这样做的原因是这样做的安全性和性能影响。但是,我认为在某些情况下它很重要,并且解决方案似乎很复杂,而且非常特定于场景。我遇到了一篇很好的文章,至少帮助我了解了我的一些选择。它不专注于跨实例访问,但确实提供了我正在寻找的线索。我鼓励您检查一下:

http://www.sommarskog.se/grantperm.html

我仍然会对解决该问题的其他解决方案感兴趣,但是现在我的解决方案有两个方面。首先,如果我绝对需要通过一个存储过程访问两个数据库,则必须使用Windows登录名。但是,我会尽可能避免这种情况,因为它确实会导致性能问题(多服务器锁定,网络复杂性,无法优化查询等)。其次,我通过单独的,特定于数据库的调用将每个数据库中的数据引入。这意味着我在合并数据之前将数据带回客户端。它没有我想要的性能或清洁程度,但它似乎是最安全的解决方案。


1

如果需要访问两个SQL Server实例之间的数据库对象,则建议使用以下方法之一:

  1. 在两个实例之间创建并使用链接服务器,并具有访问目标(远程)实例上的对象的适当权限。
  2. 使用SSIS并从SQL Server的源实例调用该程序包。根据所使用的SQL Server版本,您可以具有SQL Agent作业(不计划运行,但由存储过程调用),或使用SSISDB调用SSIS包,该包将访问远程实例上的数据库对象。
  3. 将逻辑移到中间层(或客户端应用程序端)
  4. 创建CLR来访问远程数据库对象其中,我可能会使用CLR来访问远程实例服务器并运行执行存储过程。您将需要授予源SQL Server实例在远程SQL Server实例访问权限下运行的帐户。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.