【问题标题】:stored procedure permissions and execute存储过程权限和执行
【发布时间】:2011-12-01 12:20:06
【问题描述】:

我有一个 SQL 用户,我明确授予了 Execute 特定存储过程的权限。此存储过程包含一个 truncate 语句。用户无法执行该过程并收到错误:

找不到对象 TableName,因为它不存在或您没有权限。

如果我将存储过程更改为使用Delete 而不是截断,则用户可以执行该过程。

我需要做什么来允许用户执行这个存储过程,而不给用户更多的访问权限?

【问题讨论】:

标签: sql-server stored-procedures


【解决方案1】:

来自 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 创建自定义权限集。"

【讨论】:

    【解决方案2】:

    你可以试试这个:

    create procedure SpName
    with execute as owner
    as
    truncate table TableName
    go
    

    然后给用户分配权限

    grant execute on TruncTable to User
    

    【讨论】:

    • 我得到了另一个答案,但我很欣赏这个例子 +1
    【解决方案3】:

    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”,它将模拟特定用户 OR... 模拟“login_name” with 将模拟特定登录。

    大多数情况下,您只需向存储过程授予 EXECUTE 权限,然后将权限授予在存储过程中引用的所有对象。

    通过这种方式,您无需授予隐式权限(例如:更新数据或调用其他 procs)。所有权链为您处理这个问题。这对于动态 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 绝对没有授予修改表或读取或修改此表中的任何数据的权限。

    它仅具有完成此过程上下文中编码的特定任务所需的权限。

    这种创建存储过程的方法非常有用,该存储过程可以执行需要提升的安全权限而无需永久分配这些权限的任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-14
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 2012-10-28
      • 2011-02-18
      相关资源
      最近更新 更多