代码之家  ›  专栏  ›  技术社区  ›  ercan

我可以将SP中的执行上下文从所有者更改为调用者吗?[SQL Server 2005]

  •  2
  • ercan  · 技术社区  · 15 年前

    是否可以将执行上下文更改为 呼叫者 在使用创建的存储过程中 作为所有者执行 是吗?下面是一个简单的例子:

    服务器实例中有多个登录名和数据库。假设每个人都有一个名为 当前工作 在他自己的数据库中,但没有人可以访问其他人的表。即使是老板也不允许访问员工的数据库,除非雇主决定让老板查看他的表。当雇主认为他的工作已经完成时,他应该将表内容提交给老板的数据库。然而,老板不想让他的雇主在他的表中插入任何东西,因为有一种业务逻辑他想实现(假设他想把承诺记录到某个地方)。所以他希望这种情况只能在自己的控制下发生,也就是说,在他写的一个SP中。他写了一个如下的SP,在他的数据库中为每个登录名(每个员工)创建用户,然后将该SP的Grant Execute授予所有雇主。当一个员工完成工作后,他只需打电话给这个SP,一切都应该很好:

    CREATE PROCEDURE boss.dbo.commit_work
    WITH EXECUTE AS OWNER AS
    BEGIN
       EXECUTE AS CALLER  -- It should be OK, since this is the default way of calling an SP anyway, thinks the boss
       SELECT * INTO ##tmptable FROM current_work  -- No prefix should mean default DB/Schema of the caller, thinks the boss
       REVERT  -- Back to OWNER's context, which happens to be the boss
    
       INSERT INTO boss.allwork
       SELECT * FROM ##tmptable
    END
    

    然而,事情并不像他预期的那样发展。雇主可以执行标准普尔,但他们得到了一个错误的说法 “服务器主体”boss“无法访问当前安全上下文下的数据库”boss“。” ,这让老板很不高兴(btw boss是老板的登录名。)

    你知道出了什么问题吗?或者,您是否看到了实现这种场景的另一种方法,在这种情况下,除非在SP中执行,否则任何人都不应该访问其他人的DB?当我有选择的时候,我会在应用程序级别做这样的事情,但是由于我们当前环境的要求,我被绑定到数据库级别。谢谢!

    1 回复  |  直到 15 年前
        1
  •  2
  •   ercan    15 年前

    我找到了答案 here 在ErlangSommarskog的这篇伟大的文章中,“通过存储过程授予权限”。我建议你阅读整篇文章来领会这个想法。我所要做的就是创建一个本地代理用户,并赋予它适当的权限:

    CREATE USER boss_proxy WITHOUT LOGIN
    GRANT INSERT ON boss.allwork TO boss_proxy 
    
    CREATE PROCEDURE boss.dbo.commit_work
    WITH EXECUTE AS boss_proxy AS
    BEGIN
       EXECUTE AS CALLER  -- It IS OK, indeed
       SELECT * INTO ##tmptable FROM current_work  -- No prefix means default DB/Schema of the caller
       REVERT  -- Back to boss_proxy's context
    
       INSERT INTO boss.allwork
       SELECT * FROM ##tmptable
    END