SQL 服务器存储过程和与其他数据库的权限

SQL Server stored procedures and permissions with other databases

我正在为一些新用户配置数据库帐户。我想出了以下解决方案,这是让帐户正常工作的 99% 的方法,但我遇到了一个我无法解决的问题。

首先,我使用 SQL 服务器身份验证创建了一个新登录名,然后授予他们对所有存储过程的 EXECUTE 权限。这允许他们 运行 所有这些,但他们无法查看代码,也无法查看数据库表。

我在存储过程中添加了以下内容:

WITH EXEC AS OWNER

这允许存储过程 运行 作为我们通常使用的默认帐户,并且具有 db_owner 的作用。这允许新用户 运行 所有存储过程并且在我遇到以下问题之前效果很好:

一些存储过程(所有这些都使用动态 SQL)调用一些同义词 link 到其他两个数据库(历史和数据集市数据库)中的表。这给了我以下错误:

The server principal "{username}" is not able to access the database "{database name}" under the current security context.

我在 WITH EXEC AS 中使用的帐户是我正在使用的所有三个数据库的 db_owner

我该怎么做才能解决这个问题?非常感谢

EXECUTE AS Owner 是一个数据库沙箱。想想看,必须。否则,数据库 管理员可以发布 EXECUTE AS USER = 'somesystemadmin' 并将自己提升为 实例 级别的管理员。详情见Extending Database Impersonation by Using EXECUTE AS:

when impersonating a principal by using the EXECUTE AS USER statement, or within a database-scoped module by using the EXECUTE AS clause, the scope of impersonation is restricted to the database by default. This means that references to objects outside the scope of the database will return an error.

解决办法很简单:签署程序。参见 Call a procedure in another database from an activated procedure for an example. Read more at Module Signing and Signing Stored Procedures in SQL Server