【问题标题】:SQL Server Execute ImpersonationSQL Server 执行模拟
【发布时间】:2012-04-20 04:51:13
【问题描述】:

和...有什么区别

execute as user = 'testuser'

execute as login = 'testuser'

我在这些登录名下执行一个跨数据库过程,它与作为登录名的执行一起工作,但不以用户身份执行。这是说服务器主体“testuser”无法在安全上下文下访问数据库“xxx”。

当我在两个命令之后SELECT SYSTEM_USER 时,我看到它设置为'testuser'

【问题讨论】:

    标签: sql sql-server-2008 sql-server-2005 impersonation


    【解决方案1】:

    execute as login 提供对整个服务器的模拟,因为登录是在服务器级别。由于用户是按数据库定义的,execute as user 模拟仅适用于特定数据库,这就是您在跨数据库时看到错误的原因。

    【讨论】:

      【解决方案2】:

      EXECUTE AS 可以添加到存储过程、函数、触发器等中。

      执行示例:

      CREATE PROCEDURE dbo.MyProcedure
            WITH EXECUTE AS OWNER
      

      在这种情况下,您正在冒充被调用模块的所有者

      您也可以冒充 SELF,或创建或更改模块的 USER 或... 模拟 CALLER ,这将使模块能够获得当前用户的权限,或者...... 模拟 OWNER,这将获得被调用的过程的所有者的许可 OR... 模拟'user_name',它将模拟特定用户或... impersonate 'login_name' with 将模拟特定的登录。

      对存储过程等对象设置权限可以通过

      GRANT EXECUTE ON <schema>.<procedurename> to <username>; 
      

      但是,您可能还想在登录和用户级别授予安全权限。

      您需要确定并授予必要的权利 对于需要访问(例如执行)的对象。考虑使用"EXECUTE AS" 功能,它可以模拟另一个用户 验证执行代码所需的权限而不必须授予所有底层对象(例如表)的所有必要权限。

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

      通过这种方式,您不需要赋予隐式权限(例如:更新数据或调用额外的 procs)。 所有权链接为您处理此问题。 这对于动态 sql 尤其有用,或者如果您需要创建提升的安全任务,例如 CREATE TABLE. EXECUTE AS 是考虑这些的方便工具。

      这个例子可能有助于澄清所有这些:

      --Create a user called NoPrivUser with public access to a database (e.g. 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
      AS
      IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].MyTable') AND type in (N'U')) 
      CREATE TABLE MyTable (PKid int, column1 char(10)) 
      INSERT INTO MyTable
      VALUES (1,'ABCDEF')
      
      GO
      
      GRANT EXEC ON dbo.MyProcedure TO NoPrivUser;
      GO
      

      -- 现在以 NoPrivUser 身份登录到您的数据库服务器并运行以下命令。

      use dbadb
      go
      
      EXEC dbo.MyProcedure
      
      --(1 row(s) affected)
      

      现在尝试在以 NoPrivuser 身份登录时从新表中进行选择。

      您将获得以下信息:

      select * from MyTable
      go
      

      消息 229,级别 14,状态 5,第 1 行 SELECT 权限在 对象“MyTable”、数据库“DBAdb”、模式“dbo”。

      这是意料之中的,因为您仅在以 NoPrivUser 身份登录时在 Owner 的安全上下文中运行了该过程。
      NoPrivUser 因为没有实际读取表的权限,只是执行创建和插入行的过程。

      使用 EXECUTE AS 子句,存储过程在对象所有者的上下文中运行。此代码成功创建 dbo.MyTable 并成功插入行。

      在此示例中,用户“NoPrivUser”绝对没有授予修改表或读取或修改此表中任何数据的权限。
      它仅具有完成此过程上下文中编码的特定任务所需的权限。

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

      【讨论】:

        【解决方案3】:

        登录范围在服务器级别,而用户范围在当前数据库级别

        http://msdn.microsoft.com/en-us/library/ms181362.aspx

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-12
          • 1970-01-01
          • 2017-02-11
          • 2014-01-17
          • 2011-09-23
          • 2014-02-23
          • 2012-01-02
          • 2013-08-14
          相关资源
          最近更新 更多