Sql server 存储过程和权限-执行是否足够?

Sql server 存储过程和权限-执行是否足够?,sql-server,stored-procedures,permissions,Sql Server,Stored Procedures,Permissions,我有一个SQLServer2008数据库,所有对底层表的访问都是通过存储过程完成的。一些存储过程只是从表中选择记录,而其他存储过程则更新、插入和删除记录 如果存储过程更新表,执行存储过程的用户是否还需要对受影响表的更新权限,或者他们对存储过程的执行权限是否足够 基本上,我想知道给用户对存储过程的EXECUTE权限是否足够,或者我是否需要给他们对表的SELECT、UPDATE、DELETE和INSERT权限,以便存储过程工作。多谢各位 [EDIT]在我的大多数存储过程中,似乎执行就足够了。然而,我

我有一个SQLServer2008数据库,所有对底层表的访问都是通过存储过程完成的。一些存储过程只是从表中选择记录,而其他存储过程则更新、插入和删除记录

如果存储过程更新表,执行存储过程的用户是否还需要对受影响表的更新权限,或者他们对存储过程的执行权限是否足够

基本上,我想知道给用户对存储过程的EXECUTE权限是否足够,或者我是否需要给他们对表的SELECT、UPDATE、DELETE和INSERT权限,以便存储过程工作。多谢各位


[EDIT]在我的大多数存储过程中,似乎执行就足够了。然而,我发现在使用“Execute sp_Executesql”的存储过程中,Execute是不够的。所涉及的表需要具有在“sp_Executesql”中执行的操作的权限。

对存储过程的执行权限就足够了

CREATE TABLE dbo.Temp(n int)

GO
DENY INSERT ON dbo.Temp TO <your role>
GO
CREATE PROCEDURE dbo.SPTemp(@Int int)
AS

INSERT dbo.Temp
SELECT  @Int 

GO

GRANT EXEC ON dbo.SPTemp TO <your role>

GO

但是,如果dbo.SPTemp中存在试图插入dbo.Temp的动态SQL,则该操作将失败。在这种情况下,需要授予表的直接权限。

如果表和proc具有相同的所有者,则不检查表的权限(包括拒绝)。只要模式具有相同的所有者,它们也可以位于不同的模式中

请参阅MSDN上的

编辑,来自已删除答案的注释


上下文始终是当前登录名,除非
executeas
AS-used:只检查引用的对象DML权限。在未向referencedtable分配任何权限的存储过程中尝试对象ID(referencedtable)。它给出空值。如果由存储过程的所有者执行,那么它将给出一个值,因为owener对referencedtable具有权限,对执行插入、更新或删除操作的存储过程具有执行权限就足够了。您不需要在表级别授予这些权限。事实上,我不鼓励这种做法。使用存储过程可以更好地控制更改的发生方式。例如,您可能希望在允许更新之前进行一些检查。使用存储过程也有助于防止重大事故——比如删除表中的所有行,因为有人忘记了WHERE子句

非常感谢您!我也有类似的问题。这让我找到了答案

我试图在一个存储过程中trunctate一个表,该存储过程调用嵌套在IF语句中的其他存储过程

我的错误是

服务器主体“domain\my\u id”无法在当前安全上下文下访问数据库“2nd\u DB”。

我给了调用存储过程执行截断(作为SELF执行)的权限,这导致了一个问题,因为SELF没有对第二个DB的权限。我们的解决方案是将truncate移动到另一个SP,包括executeas SELF。现在我们调用truncate SP,执行数据处理,进行逻辑确定,并调用相应的第三个SP。

也许您可以使用

“以所有者身份执行”

创建存储过程时,例如:

create procedure XXX
with execute as owner
as
begin
...
end
go

然后,您只需要向用户授予存储过程的
EXECUTE
权限
XXX

,如果没有错的话,这至少是一种误导。您的示例之所以有效,是因为过程的所有者和表的所有者相同,并且所有权链接跳过了访问检查。如果过程的所有者不是表的所有者,而只是对其拥有控制权限(即拥有所有权限,但不是所有者),则示例将失败。@Remu,您的场景需要有一个db_所有者角色的成员才能通过。在另一个答案中,@RemusRusanu链接到另一个选项:1)创建证书;2) 创建与该证书关联的用户;3) 授予该用户适当的权限[受保护的资源];和4)每次更改存储过程(,链接到:)时,使用证书对存储过程进行签名。签名将证书用户权限添加到当前用户令牌中,SQL Server在调用系统过程和通过EXEC()或sp_executesql调用的动态SQL时会保留该令牌。因此存储过程成功了。我担心在使用动态SQL查询时,您需要授予对基础对象的权限。我已经更新了答案以反映这一点。@Noel-你是对的。我发现我需要允许datareader为用户访问表。谢天谢地,这对我来说不是问题,因为所有用户都可以查看所有数据;2) 创建与该证书关联的用户;3) 授予该用户适当的权限[受保护的资源];和4)每次更改存储过程时,都要使用证书对存储过程进行签名(stackoverflow.com/a/4081604/6894566,链接到:sommarskog.se/grantperm.html#Certificates)。签名将证书用户权限添加到当前用户令牌中,SQL Server在调用系统过程和通过EXEC()或sp_executesql调用的动态SQL时会保留该令牌。因此存储过程成功了。
OBJECT\u ID
提示非常有用;我需要一种方法来检查用户是否能够执行存储过程,这很好地解决了我的问题。我们希望仅通过存储过程向用户提供对表的访问,这是可行的。该表不必与存储过程属于同一架构。(搜索词)sp_executesql Azure SQL Server动态SQL对SQL Azure上的动态SQL的特殊权限(结束关键字)。在Azure SQL上,这似乎是一个相当温和的错误。在SQLAzure中,您通常有不同的用户上下文,而这一细节正是您所要寻找的。在这种情况下,您需要查看袁刘的答案
create procedure XXX
with execute as owner
as
begin
...
end
go