SQL CLR触发器,如何通过透明代码调用关键代码使程序集受信任?

我已经潜入研究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数据提供程序:消息6522,级别16,状态1,过程AfterMarketSessionInserted,第1行在执行用户定义的例程或聚合“AfterMarketSessionInserted”期间发生.NET Framework错误:System.MethodAccessException : 尝试通过安全透明方法 ‘.Database.Triggers.MarketSessionTriggers.AfterMarketSessionInserted()’ 访问安全关键方法 ‘Quartz.Impl.StdSchedulerFactory..ctor(System.Collections.Specialized.NameValueCollection)’ 失败。

Assembly’Database,Version = 1.0.5275.15169,Culture = neutral,PublicKeyToken = null’部分受信任,这导致CLR使其完全安全透明,而不管程序集本身是否有任何透明度注释。 为了访问安全关键代码,必须完全信任此程序集。 System.MethodAccessException:at 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_ACCESSUNSAFE ,您需要执行以下操作之一:

  • 将包含程序集的数据库设置为TRUSTWORTHY = ON。 这假设数据库的所有者具有UNSAFE ASSEMBLY服务器级权限(通常是这种情况)。 虽然这个选项更快/更容易,但由于TRUSTWORTHY = ON是一个相当开放的安全漏洞,因此不是首选。
  • 使用密码对程序集签名,从程序集创建非对称密钥,从非对称密钥创建登录,授予登录UNSAFE ASSEMBLY权限。 这是首选方法。

如果您想更详细地了解SQLCLR安全性,特别是关于SAFE程序集的限制,请查看我在SQL Server Central上编写的这篇文章 (阅读该站点上的文章需要免费注册)。

一些其他信息:如果您选择签署程序集和创建非对称密钥的首选方法,请参阅此MSDN文章

下面的SQL片段来自上述文章。 在master数据库中创建密钥并登录:

 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;