我在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???)
答案 0 :(得分:1)
是的,Context Connection
位于调用者(或EXECUTE AS
语句的CREATE PROCEDURE
子句中指定的用户的安全上下文中,但默认为{{1} })。
SQLCLR存储过程与T-SQL存储过程之间的行为不同的原因是:
T-SQL存储过程正在利用所有权链接来暗示与正在执行的代码相同的所有者的相关对象的权限。
SQLCLR存储过程实际上是提交动态SQL(因为无法在SQLCLR对象中预编译代码),这会破坏所有权链接。
如果您需要特殊权限,则需要使用模块签名,如下所示:
EXECUTE AS CALLER
权限给基于证书或基于密钥的用户EXECUTE
签署非“隐藏”存储过程(如果可见的是T-SQL或SQLCLR,则无关紧要)。ADD SIGNATURE