CLR 集成代码访问安全性
公共语言运行时 (CLR) 支持用于托管代码的一种称为代码访问安全性的安全模式。 在这种模式下,根据代码的标识来对程序集授予权限。 有关详细信息,请参阅 .NET Framework 软件开发包中的“代码访问安全性”部分。
决定授予程序集的权限的安全策略定义在三个不同的位置:
计算机策略:这是对安装了 SQL Server 的计算机中运行的所有托管代码都有效的策略。
用户策略:这是对进程承载的托管代码有效的策略。 对于 SQL Server,用户策略特定于 SQL Server 服务运行时所使用的 Windows 帐户。
主机策略:这是由 CLR(在本例中为 SQL Server)的主机设置的策略,对该主机中运行的托管代码有效。
CLR 支持的代码访问安全机制基于如下假设:运行时既可承载完全可信任的代码,也可承载部分可信任的代码。 受 CLR 代码访问安全性保护的资源通常由托管应用程序编程接口包装,这些接口要求提供相应的权限才允许访问资源。 仅当调用堆栈中的所有调用方(在程序集级别)都具有相应的资源权限时,才会满足对权限的要求。
在 SQL Server 中运行时授予托管代码的代码访问安全性权限集为以上三种策略级别授予的权限集的交集。 即使 SQL Server 向加载到 SQL Server 中的程序集授予一个权限集,赋予用户代码的最终权限集仍可能受用户和计算机级别策略的进一步限制。
SQL Server 主机策略级别权限集
SQL Server 主机策略级别授予程序集的代码访问安全性权限集由创建该程序集时指定的权限集决定。 有三个权限集:SAFE、EXTERNAL_ACCESS 和 UNSAFE(使用 CREATE ASSEMBLY (Transact-SQL) 的 PERMISSION_SET 选项指定)。
SQL Server 在承载 CLR 的同时向其提供了主机级别安全策略级别;该策略为始终有效的两个策略级别下的附加策略级别。 会为 SQL Server 创建的每个应用程序域设置此策略。 此策略并不用于在 SQL Server 创建 CLR 实例时有效的默认应用程序域。
SQL Server 主机级别策略由用于系统程序集的 SQL Server 固定策略和用于用户程序集的用户指定策略组成。
用于 CLR 程序集和 SQL Server 系统程序集的固定策略授予其完全信任。
SQL Server 主机策略的用户指定部分基于为每个程序集指定三个权限存储桶之一的程序集所有者。 有关以下列出的安全权限的详细信息,请参阅 .NET Framework SDK。
SAFE
只允许内部计算和本地数据访问。 SAFE 是最具限制性的权限集。 由具有 SAFE 权限的程序集执行的代码无法访问外部系统资源,例如文件、网络、环境变量或注册表。
SAFE 程序集具有以下权限和值:
权限 |
值/说明 |
---|---|
SecurityPermission |
Execution: 用于执行托管代码的权限。 |
SqlClientPermission |
Context connection = true、context connection = yes:只能使用上下文连接并且连接字符串只能指定值“context connection=true”或“context connection=yes”。 AllowBlankPassword = false: 不允许使用空密码。 |
EXTERNAL_ACCESS
EXTERNAL_ACCESS 程序集与 SAFE 程序集具有相同的权限,此外,还可以访问外部系统资源,例如文件、网络、环境变量和注册表。
EXTERNAL_ACCESS 程序集还具有以下权限和值:
权限 |
值/说明 |
---|---|
DistributedTransactionPermission |
Unrestricted: 不允许使用分布式事务。 |
DNSPermission |
Unrestricted: 用于从域名服务器请求信息的权限。 |
EnvironmentPermission |
Unrestricted: 允许对系统和用户环境变量进行完全访问。 |
EventLogPermission |
Administer: 允许执行以下操作:创建事件源、读取现有日志、删除事件源或日志、对项做出响应、清除事件日志、侦听事件以及访问所有事件日志的集合。 |
FileIOPermission |
Unrestricted: 允许对文件和文件夹进行完全访问。 |
KeyContainerPermission |
Unrestricted: 允许对密钥容器进行完全访问。 |
NetworkInformationPermission |
Access: 允许进行 Ping 操作。 |
RegistryPermission |
允许对 HKEY_CLASSES_ROOT、HKEY_LOCAL_MACHINE、HKEY_CURRENT_USER、HKEY_CURRENT_CONFIG 和 HKEY_USERS. 的读取权限。 |
SecurityPermission |
Assertion: 能够断言此代码的所有调用方都具有执行该操作所需的权限。 ControlPrincipal: 能够操作主体对象。 Execution: 用于执行托管代码的权限。 SerializationFormatter: 能够提供序列化服务。 |
SmtpPermission |
Access: 允许与 SMTP 主机端口 25 建立出站连接。 |
SocketPermission |
Connect: 允许与传输地址建立出站连接(所有端口、所有协议)。 |
SqlClientPermission |
Unrestricted: 允许对数据源进行完全访问。 |
StorePermission |
Unrestricted: 允许对 X.509 证书存储区进行完全访问。 |
WebPermission |
Connect: 允许与 Web 资源建立出站连接。 |
UNSAFE
UNSAFE 允许程序集不受限制地访问 SQL Server 内部和外部的资源。 从 UNSAFE 程序集内部执行代码时也可以调用非托管代码。
UNSAFE 程序集被授予 FullTrust。
安全说明 |
---|
对于执行计算和数据管理任务而无需访问 SQL Server 外部资源的程序集,SAFE 是推荐的权限设置。 对于访问 SQL Server 外部资源的程序集,建议使用 EXTERNAL_ACCESS。 EXTERNAL_ACCESS 程序集默认情况下以 SQL Server 服务帐户身份执行。 EXTERNAL_ACCESS 代码可以显式模拟调用方的 Windows 身份验证安全上下文。 因为默认情况下是以 SQL Server 服务帐户的身份执行,所以用于执行 EXTERNAL_ACCESS 的权限只能授予以服务帐户身份运行的受信登录名。 从安全角度来看,EXTERNAL_ACCESS 和 UNSAFE 程序集是等同的。 但是,EXTERNAL_ACCESS 程序集提供了 UNSAFE 程序集所不具备的各种可靠性和健壮性保护。 指定 UNSAFE 将允许程序集中的代码对 SQL Server 进程空间执行非法操作,因此可能会损害 SQL Server 的健壮性和可扩展性。 有关在 SQL Server 中创建 CLR 程序集的详细信息,请参阅 管理 CLR 集成程序集。 |
访问外部资源
如果用户定义类型 (UDT)、存储过程或其他类型的构造程序集均使用 SAFE 权限集进行注册,则在构造中执行的托管代码将无法访问外部资源。 但是,如果指定了 EXTERNAL_ACCESS 或 UNSAFE 权限集,并且托管代码尝试访问外部资源,则 SQL Server 会应用以下规则:
条件 |
结果 |
---|---|
执行上下文与 SQL Server 登录名相对应。 |
拒绝访问外部资源的尝试并引发一个安全异常。 |
执行上下文与 Windows 登录名相对应并且执行上下文为原始调用方。 |
在 SQL Server 服务帐户的安全上下文下访问外部资源。 |
调用方不是原始调用方。 |
拒绝访问并引发一个安全异常。 |
执行上下文与 Windows 登录名相对应并且执行上下文是原始调用方,而该调用方已被模拟。 |
访问使用调用方安全上下文,而非服务帐户。 |
权限集汇总
下表总结了授予 SAFE、EXTERNAL_ACCESS 和 UNSAFE 权限集的权限以及为其设定的限制。
SAFE |
EXTERNAL_ACCESS |
UNSAFE |
|
Code Access Security Permissions |
仅执行 |
执行和访问外部资源 |
不受限制(包括 P/Invoke) |
Programming model restrictions |
是 |
是 |
无限制 |
Verifiability requirement |
是 |
是 |
否 |
Local data access |
是 |
是 |
是 |
Ability to call native code |
否 |
否 |
是 |