SQL Server 编程和宿主保护属性
更新:2007 年 11 月
若要实现在 SQL Server 宿主中加载和执行托管代码的功能,需要满足宿主对代码访问安全性和宿主资源保护的要求。 代码访问安全性要求由以下三个 SQL Server 权限集之一指定:SAFE、EXTERNAL-ACCESS 或 UNSAFE。在 SAFE 或 EXTERNAL-ACCESS 权限集内执行的代码必须避免应用了 HostProtectionAttribute 属性的某些类型或成员。HostProtectionAttribute 并非是像可靠性保证一样安全的安全权限,原因在于它标识宿主可能不允许的特定代码构造(类型或成员)。 使用 HostProtectionAttribute 会强制执行可帮助保护宿主稳定性的编程模型。
宿主保护属性
宿主保护属性标识不适合宿主编程模型的类型或成员,并表示可靠性威胁的以下递增级别:
为良性。
可导致反序列化服务器托管的用户代码。
可导致反序列化服务器进程本身。
SQL Server 不允许使用具有 HostProtectionAttribute(指定 SharedState、Synchronization、MayLeakOnAbort 或 ExternalProcessMgmt 的 HostProtectionResource 值)的类型或成员。这阻止程序集调用能够启用共享状态,执行同步,导致终止时资源泄漏或影响 SQL Server 进程的完整性的成员。
禁用的类型和成员
下表标识其 HostProtectionResource 值被 SQL Server 禁用的类型和成员。
命名空间 |
类型或成员 |
---|---|
Microsoft.Win32 |
PowerModeChangedEventHandler 委托 |
System.Collections |
|
System.ComponentModel |
CollectionChangeEventHandler 委托 ComponentChangedEventHandler 委托 ComponentChangingEventHandler 委托 ComponentRenameEventHandler 委托 DesignerTransactionCloseEventArgs 类 DesignerTransactionCloseEventHandler 委托 DesigntimeLicenseContextSerializer 类 ComponentSerializationService 类 InvalidAsynchronousStateException 类 InvalidEnumArgumentException 类 BeginInvoke 方法 License 类 ListSortDescriptionCollection 类 ProgressChangedEventHandler 委托 PropertyChangedEventHandler 委托 PropertyDescriptorCollection 类 |
System.Diagnostics |
EventLog.SynchronizingObject 属性 Process 类 |
System.IO |
|
System.Reflection.Emit |
|
System.Text |
|
System.Threading |
Monitor 类 Mutex 类 Thread.AllocateNamedDataSlot 方法 Thread.Join 方法 Thread.Start 方法 Thread.TrySetApartmentState 方法 Timer 类 |
System.Timers |
Timer 类 |
System.Web.Configuration |
|
System.Windows.Forms |
SQL Server 权限集
SQL Server 允许用户指定部署到数据库中的代码的可靠性要求。当程序集上载到数据库中时,程序集作者可为该程序集指定以下三个权限集中的一个:SAFE、EXTERNAL-ACCESS 或 UNSAFE。
权限集 |
SAFE |
EXTERNAL-ACCESS |
UNSAFE |
---|---|---|---|
代码访问安全性 |
仅执行 |
执行并访问外部资源 |
无限制 |
编程模型限制 |
是 |
是 |
无限制 |
可验证性要求 |
是 |
是 |
否 |
调用本机代码的能力 |
否 |
否 |
是 |
SAFE 是最可靠和安全的模式,并且在允许的编程模型方面也具有关联的限制。SAFE 代码具有高可靠性和安全性功能。SAFE 程序集授予了足够的权限,可以运行、执行计算以及访问本地数据库。SAFE 程序集需要具有可验证的类型安全性,并且不允许调用非托管代码。
EXTERNAL-ACCESS 提供了一个中间安全选项,允许代码访问数据库外部的资源,而且仍然拥有与 SAFE 相同的可靠性和安全性。
UNSAFE 用于仅能由数据库管理员创建的高度受信任的代码。这种受信任代码没有代码访问限制,并且可以调用非托管(本机)代码。
SQL Server 使用宿主级别的代码访问安全策略层设置宿主策略,该宿主策略根据存储在 SQL Server 目录中的权限集授予三个权限集之一。运行在数据库内的托管代码始终获取这些代码访问权限集中的一个。
编程模型限制
SQL Server 中的托管代码的编程模型需要函数、过程和类型,这些函数、过程和类型无需使用跨多个调用保持的状态以及在多个用户会话之间共享状态。此外,如前所述,共享状态的存在可导致能够影响应用程序的可伸缩性和可靠性的重要异常。
出于上述考虑,SQL Server 不允许使用静态变量和静态数据成员。对于 SAFE 和 EXTERNAL-ACCESS 程序集,SQL Server 在执行 CREATE ASSEMBLY 时检查程序集的元数据,并在发现使用了静态数据成员和变量时使此类程序集的创建失败。