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

Vu *_*yen 6 c# sql-server security sqlclr

我已经潜入研究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();
Run Code Online (Sandbox Code Playgroud)

错误:

(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)' 失败.

程序集"数据库,版本= 1.0.5275.15169,Culture = neutral,PublicKeyToken = null"部分受信任,这使得CLR使其完全安全透明,而不管程序集本身是否有任何透明度注释. 为了访问安全关键代码,必须完全信任此程序集. System.MethodAccessException:at Database.Triggers.FinancialMarketSessionTriggers.AfterFinancialMarketSessionInserted()

--------------

为什么SQL CLR触发器代码被视为透明代码并且部分受信任?

如何使SQL CLR触发器代码不是透明代码或使其完全受信任?

我愿意接受建议.

Sol*_*zky 5

为什么SQLCLR代码仅部分受信任?

默认情况下,在SQL Server内部运行的CLR代码(即"SQLCLR")受到严格限制,以免降低SQL Server的安全性或稳定性.

你如何让SQLCLR完全信任?

程序集中的CLR代码可以执行的操作(主要)由PERMISSION_SET每个程序集的属性控制.如果您未指定PERMISSION_SET何时加载程序集CREATE ASSEMBLY,则默认值将SAFE是最受限制且不完全受信任的.为了使CLR代码能够到达SQL Server外部(到网络,文件系统,操作系统等),您需要至少将程序集设置为EXTERNAL_ACCESS,但这仍然不完全可信.要被视为完全信任,您需要将程序集设置为UNSAFE.

要将任何程序集设置为EXTERNAL_ACCESSUNSAFE,您需要执行以下操作之一:

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

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