3

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

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


一个数据库称为“内部”,并有一个名为“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'.


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

4

4 回答 4

3

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

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

If you're using SQL Server 2005 and want to be able to grant only EXEC permissions to CALLER credentials, then this article may help shed some light on how to do so. In my opinion, that's the "correct" way to do things, though I'm sure there are probably others who might disagree (though I'd probably stick to my argument on this point).

Anyway, I'm not sure how much I've clarified the issue for you with this post. SQL Server permissions management is indeed a bit of a deep end when you first delve into the whole issue. It's not making it any easier that you're having to deal with setting them up accross multiple databases.

于 2009-02-06T16:28:51.703 回答
1

You can enable Croos-Database ownership, without having to give select permissions on the table that your sproc is calling. But use at your own risk. I use it for the scenraio you are describing:

alter database dbname set db_chaining on

于 2009-02-06T18:41:57.753 回答
0

When you go across to a different database on the same instance, each "commmand" has permissions on its tables and views evaluated by the destination database in the same context before it is allowed to run.

This is unlike being completely in the same database as the SP, where the SELECT permissions are not required for tables referred to in an SP for which you have EXEC rights.

You can use EXECUTE AS to execute as a person who does have the rights, or another alternative is to make a VIEW in the second database which returns only the columns they need, or to set column-level permissions on the tables, or to create an SP and call it (you will have to insert the results into a temporary table, so not terribly efficient).

于 2009-02-06T17:15:03.233 回答
0

Connection string user!

Definitely a permissions issue, but who?

For me, calling stored procedure that (tried to) accesses a table in a different database, it was the user in the connection string that had to be GRANTed permissions.

于 2012-08-16T16:13:36.780 回答