繁体   English   中英

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

[英]SQL CLR Rights: Call Stored Procedure in CLR Procedure

我在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

所以我的问题是,如何像在T-SQL存储过程中进行的连接那样在SQL-CLR存储过程中设置连接字符串。 我不想在SQL-CLR连接字符串中设置数据库名称。 如果我可以从SqlContext获取数据库名称,那对我来说可以:

SqlConnection("server=LOCALHOST;integrated security=yes;database=" &
  SqlContext.???CurrentDatabase???)

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

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

  • T-SQL存储过程正在使用所有权链来暗含对与正在执行的代码相同所有者的相关对象的许可。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM