存储过程所有权链接

时间:2020-03-06 14:53:11  来源:igfitidea点击:

我的数据库中有几个存储过程,这些存储过程用于从存放在单独数据库中的数据集市加载数据。这些过程通常采用以下形式:

CREATE PROCEDURE load_stuff
WITH EXECUTE AS OWNER AS
INSERT INTO my_db.dbo.report_table
(
  column_a
)
SELECT
  column_b
FROM data_mart.dbo.source_table
WHERE
  foo = 'bar';

当我在SQL Server Management Studio中执行查询时,它们运行良好。当我尝试使用EXEC load_stuff执行它们时,该过程失败并显示安全警告:

服务器主体" the_user"在当前安全上下文下无法访问数据库" data_mart"。

存储过程的所有者是dbo,它是the_user(在我们的示例中)。这两个数据库的所有者也都是the_user,并且the_user映射到dbo(这是SQL Server应该执行的操作)。

为什么我会在SQL Server中看到此错误?这是因为有问题的用户被别名为dbo,并且我应该对跨数据库数据访问使用其他用户帐户吗?

编辑
我知道这是因为SQL Server默认情况下禁用跨数据库所有权链接,这很好。但是,我不确定这种情况下的最佳做法。如果有人对这种情况的最佳实践有任何意见,将不胜感激。

编辑2
最终的解决方案是在两个数据库上都将TRUSTWORTHY设置为ON。这允许在两个数据库之间进行有限的所有权链接,而无需求助于完整的数据库所有权链接。

解决方案

为什么不删除EXECUTE AS OWNER?

通常,执行SP的用户在两个数据库中都具有适当的权限,而我根本不需要这样做。

实际上,DBO是一个角色(我们可以将其视为一组用户),而不是自己的用户。 (除非我们可以使用dbo:passwordfordbo连接到SQL SERVER,否则它不是用户)。

通常,在Sql Server的美好世界中,如果授予userX有权执行storedprocY,则X有权执行Y包含的所有任务,即使他没有对Y中使用的所有对象的所有权限也是如此。

这是将业务逻辑封装在存储过程中的极其有用的功能。 (用户无法访问表,但可以执行一个存储的过程)。

当我们谈论"所有权链接"时,它表示以下含义(如果我错了,请指正我)
如果禁用所有权链接:只要所有必需的对象都在同一数据库中,则执行procedureX的权利将起作用
已启用of of chain:该"特权"将扩展到所有数据库。

希望能有所帮助,