sql - 为什么存储过程不能从另一个数据库读取表(我一定是错误地使用了 GRANT 和 DENY)

标签 sql stored-procedures database-permissions

我有两个 Microsoft SQL Server 2000 数据库,一个上的存储过程试图从另一个上读取数据。这曾经工作得很好,但由于我变得有安全意识并将登录名(SQL 用户)从“db owner”更改为“denydatareader”,调用失败了。

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


一个数据库称为“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”数据库。 当它尝试执行该过程时,出现以下错误:
对对象“Stuff”、数据库“Internal”、所有者“dbo”的 SELECT 权限被拒绝。


(如果这是一个愚蠢的问题,我深表歉意,但我一直被推到最深处,昨天才了解到 GRANT 和 DENY。我试过谷歌搜索...)

最佳答案

将 SQL 登录名与组/角色相关联(或不相关联)对于必须跟踪数据库权限的人来说更方便。由于您是这一切的新手,在担心通过组/角色管理权限之前,我会首先关注正确获取特定登录的权限。

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

如果您使用的是 SQL Server 2005 并且希望能够仅向 CALLER 凭据授予 EXEC 权限,那么 this文章可能有助于阐明如何做到这一点。在我看来,这是做事的“正确”方式,尽管我确信可能还有其他人可能不同意(尽管我可能会坚持我在这一点上的论点)。

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

关于sql - 为什么存储过程不能从另一个数据库读取表(我一定是错误地使用了 GRANT 和 DENY),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/520579/

相关文章:

java - 使用hibernate执行原生sql

sql - SQL连接两个表,并在两个表之间建立链接表-GORM/Grails

php - 如何将变量传递给 codeigniter 中的条件连接?

php - 为什么当我在 mysql 中调用存储过程时 pdo->lastInsertId() 返回 0?

sql-server - SQL Server 禁用所有触发器 - 找不到对象 "XXXX",因为它不存在或您没有权限

mysql - 指定的字段可以引用 FROM 子句中列出的多个表

sql - 检索最近执行的 SQL 命令 (T-SQL)

oracle - 如何使用 MyBatis 将 Java 对象列表传递给 Oracle 存储过程?

postgresql - 如何只允许特定用户访问数据库?

Mysql跨表更新权限问题