代码之家  ›  专栏  ›  技术社区  ›  Magnus Smith

为什么存储过程不能从另一个数据库读取表(我必须错误地使用GRANT和DENIY)

  •  3
  • Magnus Smith  · 技术社区  · 16 年前

    我有两个Microsoft SQL Server 2000数据库,其中一个数据库上的存储过程尝试从另一个数据库读取数据。这过去工作正常,但由于我变得有安全意识,并将登录名(SQL用户)从“db所有者”更改为“denydatareader”,因此调用失败。

    如果我使用“datareader”组,我可以让事情正常进行,但由于我不希望此登录具有对用户表的读取权限(ASP仅使用procs),我认为这是不明智的。如果我将用户从所有组中删除,它也会起作用!!!这样行吗?


    一个数据库称为“Internal”,有一个表称为“Stuff”。 另一个称为“WebFacing”,有一个名为“Get_Some_Data”的存储过程,它从“Internal..Stuff”中进行选择。

    我在内部数据库上运行了以下命令:
    GRANT SELECT ON Stuff TO magnus

    我在WebFacing数据库上运行了这个:
    GRANT EXECUTE ON Get_Some_Data TO magnus

    我的ASP使用SQL登录名“magnus”,并连接到“WebFacing”数据库。
    SELECT permission denied on object 'Stuff', database 'Internal', owner 'dbo'.


    (如果这是一个愚蠢的问题,我深表歉意,但我已经陷入了困境,直到昨天才知道格兰特和否认。我已经尝试过谷歌搜索了……)

    4 回复  |  直到 16 年前
        1
  •  3
  •   codemonkey    16 年前

    当我第一次开始使用SQL Server权限时,有一件事让我感到非常适合,那就是了解用于执行存储过程的权限是用于调用proc的SQL登录名的权限,还是与创建proc本身相关联的SQL登录名的权限。该术语(用于执行过程代码的一组凭据和相关权限)称为“安全上下文”,存储的过程在该上下文下运行。我最近一直在使用MySQL,但如果我没记错的话,在SQL Server上执行存储过程所使用的默认安全上下文是调用方的上下文,而不是过程所有者的上下文。这总是让我觉得有悖常理,因为在我看来,使用存储过程的一个关键优势应该是能够仅向调用方登录授予特定进程上的EXEC权限。但当我尝试这样做时,不可避免地会出现权限错误,因为我用来调用proc的凭据没有完成存储过程中包含的一个或多个操作所需的权限。

    如果您使用的是SQL Server 2005,并且希望能够仅向调用方凭据授予EXEC权限,则 this

    无论如何,我不确定我在这篇文章中为你澄清了多少问题。当您第一次深入研究整个问题时,SQL Server权限管理确实有点深奥。这并没有让你在多个数据库中设置它们变得更容易。

        2
  •  1
  •   Jojo    16 年前

    您可以启用Croos数据库所有权,而无需对存储过程调用的表授予select权限。但使用风险自负。我将其用于您描述的场景:

    alter database dbname将数据库链接设置为on

        3
  •  0
  •   Cade Roux    16 年前

    当您在同一实例上访问不同的数据库时,每个“commmand”在允许运行之前,都对其表和视图拥有权限,这些表和视图由目标数据库在同一上下文中评估。

    您可以使用EXECUTE AS以拥有权限的人的身份执行,或者另一种选择是在第二个数据库中创建一个只返回所需列的视图,或者在表上设置列级权限,或者创建一个SP并调用它(您必须将结果插入一个临时表中,因此效率不高)。

        4
  •  0
  •   Davis    12 年前

    当然是权限问题,但是谁呢?

    对我来说,调用(试图)访问不同数据库中的表的存储过程, 必须向连接字符串中的用户授予权限。

    推荐文章