SQL CLR触发器,如何使程序集由于透明代码调用关键代码而受信任
本文关键字:代码 调用 透明 信任 触发器 CLR 何使 于透明 程序集 SQL | 更新日期: 2023-09-27 18:07:58
我已经深入研究了SQL CLR。不幸的是,我的第一个例子在透明代码调用安全代码时有问题。
关键是我的SQL CLR触发器被视为透明代码。在触发器中,我使用Quartz来调用Quartz Windows服务:var properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "ServerScheduler";
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.scheduler.proxy.address"] = string.Format("tcp://{0}:{1}/{2}", "localhost", "555",
"QuartzScheduler");
var schedulerFactory = new StdSchedulerFactory(properties);
IScheduler scheduler = schedulerFactory.GetScheduler();
错误:(135,1): SQL72014: .Net SqlClient Data Provider: Msg 6522, Level 16,状态1,过程AfterMarketSessionInserted,行1。net框架执行用户定义例程或聚合时发生错误"AfterMarketSessionInserted":系统。MethodAccessException: by security transparent method ' .Database.Triggers.MarketSessionTriggers.AfterMarketSessionInserted () 访问安全关键方法'Quartz.Impl.StdSchedulerFactory. ctor(system . collections . specied . namevaluecollection)'失败。
Assembly 'Database, Version=1.0.5275.15169, Culture=neutral,PublicKeyToken=null'是部分可信的,这会导致CLR使其完全安全透明,而不考虑任何透明度程序集本身中的注释。为了访问安全关键代码,此程序集必须完全可信。系统。MethodAccessException:Database.Triggers.FinancialMarketSessionTriggers.AfterFinancialMarketSessionInserted ()
--------------
为什么SQL CLR触发器代码被认为是透明代码和部分可信?
如何使SQL CLR触发代码不是透明代码或使其可信完全?
我愿意听取建议。
为什么SQLCLR代码只被部分信任?
默认情况下,运行在SQL Server内部的CLR代码(即:"SQLCLR")是高度限制的,以免降低SQL Server的安全性和稳定性。
如何使SQLCLR完全受信任?
程序集中的CLR代码可以做什么(主要)由每个程序集的PERMISSION_SET
属性控制。如果您在通过CREATE ASSEMBLY
加载程序集时没有指定PERMISSION_SET
,则默认将是SAFE
,这是最受限制的,并且不是完全受信任。为了使CLR代码能够到达SQL Server外部(到网络,文件系统,操作系统等),您需要将程序集设置为至少EXTERNAL_ACCESS
,但这仍然不是完全可信的。为了将视为完全可信的,您需要将程序集设置为UNSAFE
。
为了将任何程序集设置为EXTERNAL_ACCESS
或UNSAFE
,您需要执行以下操作之一:
- 用密码对程序集签名,从程序集创建非对称密钥,从非对称密钥创建登录,授予登录
UNSAFE ASSEMBLY
权限。这是首选方法。 - 设置包含程序集的数据库为
TRUSTWORTHY = ON
。这假定数据库的所有者具有UNSAFE ASSEMBLY
服务器级权限(通常是这种情况)。虽然此选项更快/更容易,但由于TRUSTWORTHY = ON
是一个相当开放的安全漏洞,因此不推荐使用。
如果您想更详细地了解SQLCLR安全性,特别是关于SAFE
程序集的限制,请查看我在SQL Server Central上写的这篇文章。
其他信息:如果选择对程序集签名和创建非对称密钥的首选方法,请参阅MSDN文章
下面的SQL代码片段来自上述文章。在主数据库中创建密钥和登录:
USE master;
GO
CREATE ASYMMETRIC KEY SQLCLRTestKey FROM EXECUTABLE FILE = 'C:'MyDBApp'SQLCLRTest.dll';
CREATE LOGIN SQLCLRTestLogin FROM ASYMMETRIC KEY SQLCLRTestKey ;
GRANT UNSAFE ASSEMBLY TO SQLCLRTestLogin ;
GO
然后创建程序集:
CREATE ASSEMBLY SQLCLRTest
FROM 'C:'MyDBApp'SQLCLRTest.dll'
WITH PERMISSION_SET = UNSAFE;