我有一个SQL用户,我为特定的存储过程提供了明确的Execute
权限。此存储过程包含truncate语句。用户无法执行该过程并收到错误:
无法找到对象TableName,因为它不存在或您没有权限。
如果我改变存储过程以使用Delete
而不是截断,则用户可以执行该过程。
如果允许用户执行此存储过程而不向用户提供超出必要的访问权限,我需要做什么?
答案 0 :(得分:2)
来自MSDN:
http://msdn.microsoft.com/en-us/library/ms177570.aspx
“所需的最小权限是table_name上的ALTER。TRUNCATE TABLE权限默认授予表所有者,sysadmin固定服务器角色的成员以及db_owner和db_ddladmin固定数据库角色,并且不可转让。但是,您可以合并模块内的TRUNCATE TABLE语句,例如存储过程,并使用EXECUTE AS子句为模块授予适当的权限。有关更多信息,请参阅使用EXECUTE AS创建自定义权限集。“
答案 1 :(得分:2)
你可以试试这个:
create procedure SpName
with execute as owner
as
truncate table TableName
go
然后为用户分配权限
grant execute on TruncTable to User
答案 2 :(得分:0)
truncate table对存储过程等对象的设置权限可以通过以下方式完成:
GRANT EXECUTE ON <schema>.<object> to <user>;
但是,您可能还希望在登录和用户级别授予安全权限。您将只想确定并授予需要访问(例如执行)的对象的必要权限。考虑使用EXECUTE AS
功能,该功能允许模仿另一个用户来验证执行代码所需的权限,而不必为所有底层对象(例如表)授予所有必要的权限。 EXECUTE AS
可以添加到存储过程,函数,触发器等。
在存储过程中添加如下代码:
CREATE PROCEDURE dbo.MyProcedure WITH EXECUTE AS OWNER
在这种情况下,您冒充被调用模块的所有者。您还可以模拟SELF,或者用户创建或更改模块或者...使用CALLER,这将使模块能够接受当前用户的权限,或者...模仿OWNER,它将获得权限。被称为OR的过程的所有者...模仿'user_name',它将模拟特定用户或...模拟'login_name'将模拟特定登录。
大多数情况下,您只需要对存储过程授予EXECUTE
权限,然后将权限授予存储过程中引用的所有对象。
通过这种方式,您无需提供隐式权限(例如:更新数据或调用其他过程)。所有权链为您处理此问题。这对动态sql特别有用,或者如果您需要创建提升的安全性任务,例如CREATE TABLE
。 EXECUTE AS
是一个值得考虑的工具。
这个例子可能有助于澄清所有这些:
创建一个名为NoPrivUser的用户,对数据库具有公共访问权限(例如dbadb):
USE [master];
GO
CREATE LOGIN [NoPrivUser] WITH PASSWORD=N'ABC5%', DEFAULT_DATABASE=[dbadb],
CHECK_EXPIRATION=ON, CHECK_POLICY=ON;
GO
USE [DBAdb];
GO
CREATE USER [NoPrivUser] FOR LOGIN [NoPrivUser];
GO
注意:本程序的创建者或所有者将要求在目标数据库中创建表权。
use DBAdb
go
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
truncate table MyTable
GO
GRANT EXEC ON dbo.MyProcedure TO NoPrivUser;
GO
-- Now log into your database server as NoPrivUser and run the following.
使用EXECUTE AS
子句,存储过程在对象所有者的上下文中运行。此代码成功创建dbo.MyTable
并成功插入行。在此示例中,用户NoPrivUser
绝对没有权限修改表,或读取或修改此表中的任何数据。
它只承担完成在此过程的上下文中编码的特定任务所需的权限。
这种创建存储过程的方法非常有用,这种存储过程可以执行需要提升安全权限而无需永久分配这些权限的任务。