SQL CLR权限:在CLR过程中调用存储过程

时间:2017-03-29 12:01:30

标签: c# sql-server tsql stored-procedures sqlclr

我在T-SQL中编写了一个(私有)存储过程,该过程对用户不可见。他没有执行权限。

CREATE PROCEDURE [dbo].[GetEntries]
AS
BEGIN 
    SELECT * FROM sometable
END

然后我编写了一个CLR存储过程,用户具有执行权限。此存储过程调用我的私有过程。

using (SqlConnection conn = new SqlConnection())
{
    conn.ConnectionString = "context connection=true";
    conn.Open();

    SqlCommand command = new SqlCommand("exec dbo.[GetEntries] ", conn);
...

如果我调用公共CLR存储过程,则发生错误,我无权调用私有存储过程。我认为这是因为我的连接字符串是" context connection = true"所以存储过程在用户上下文中(用户连接)。

当我编写一个调用私有存储过程的公共(用户可见)T-SQL存储过程时,我可以执行此存储过程。

CREATE PROCEDURE [dbo].TSQLPublicSP
AS
BEGIN
    Exec  dbo.[GetEntries]
END

所以我的问题是,如何在SQL-CLR存储过程中设置连接字符串,就像它来自T-SQL存储过程的连接一样。我不想在SQL-CLR连接字符串中设置数据库名称。如果我可以从SqlContext

获取数据库名称,那对我来说没问题
SqlConnection("server=LOCALHOST;integrated security=yes;database=" &
  SqlContext.???CurrentDatabase???)

1 个答案:

答案 0 :(得分:1)

是的,Context Connection位于调用者(或EXECUTE AS语句的CREATE PROCEDURE子句中指定的用户的安全上下文中,但默认为{{1} })。

SQLCLR存储过程与T-SQL存储过程之间的行为不同的原因是:

  • T-SQL存储过程正在利用所有权链接来暗示与正在执行的代码相同的所有者的相关对象的权限。

  • SQLCLR存储过程实际上是提交动态SQL(因为无法在SQLCLR对象中预编译代码),这会破坏所有权链接。

如果您需要特殊权限,则需要使用模块签名,如下所示:

  1. 在此数据库中创建证书或非对称密钥
  2. 从证书或非对称密钥创建用户
  3. 将“隐藏”存储过程授予EXECUTE AS CALLER权限给基于证书或基于密钥的用户
  4. 使用EXECUTE签署非“隐藏”存储过程(如果可见的是T-SQL或SQLCLR,则无关紧要)。
  5. 如果您对包含此SQLCLR存储过程的方法的程序集进行了任何更改,则需要重新应用ADD SIGNATURE