WEB开发网
开发学院数据库MSSQL Server SQL Server2005SQLCLR代码安全之权限 阅读

SQL Server2005SQLCLR代码安全之权限

 2007-11-11 10:00:25 来源:WEB开发网   
核心提示: 二、 访问外部资源因为访问外部资源需要与操作系统进行交互,所以,SQL Server2005SQLCLR代码安全之权限(2),当代码尝试存取外部的资源时,存在多种要遵守的规则,基于EXTERNAL ACCESS ASSEMBLY权限,一个DBA能够控制是否存在潜在危险性的程序集能够被安装到任何数据库中,对于SAFE代
二、 访问外部资源

  因为访问外部资源需要与操作系统进行交互,所以,当代码尝试存取外部的资源时,存在多种要遵守的规则。

  对于SAFE代码来说,这种规则是简单的:如果它试图存取一个外部的资源,那么存取将被否认并且它引发一个异常。就是这些。

  对于EXTERNAL_ACCESS和UNSAFE的情况,则复杂些:

  · 规则1:如果代码在一个sql server(WINDOWS平台上强大的数据库平台)登录的安全上下文下执行(也就是说,还没有被映射到一个Windows用户或组),那么存取将被禁止并且引发一个异常。一个SQL登录并不拥有sql server(WINDOWS平台上强大的数据库平台)外的任何许可权,因此这是很重要的。

  · 规则2:如果代码在一个被映射到一个Windows登录的登录下执行,那么进行外部存取的执行上下文就是该登录的执行上下文。如果该用户能够存取Windows中的资源,那么该代码成功。如果不是,存取被否认并且引发一个异常。

  · 规则3:如果调用者不是原始的调用者(已经进行了一个执行上下文切换),那么存取被否认并且引发一个异常。

  一开始,这些规则也使我有点糊涂,但是,当我以后逐渐地越来越多地使用它们时,它们开始变得很重要了。对于规则1来说,因为一个SQL登录仅仅存在于sql server(WINDOWS平台上强大的数据库平台)世界中,所以,如果它能存取操作系统资源的话,这将是一个巨大的安全漏洞。规则2也很重要,并且它允许模拟。规则3似乎有点严格,但是我怀疑sql server(WINDOWS平台上强大的数据库平台)小组有点保守,因为上下文切换可能会是一场"管理恶梦",并且他们仍然确信不会产生安全漏洞问题。

  外部的存取规则甚至更复杂些。假定运行代码的登录已经成功"越过"上面列举的"重重封锁",但是,为了存取外部的资源-正如你可能盼望的(并且也许希望),sql server(WINDOWS平台上强大的数据库平台)并不自动地模拟当前执行上下文。代之的是,它使用sql server(WINDOWS平台上强大的数据库平台)实例的服务帐户来存取资源。或者,你也可以显式地模拟上下文登录来存取资源。这样做需要使用SqlContext对象的WindowsIdentity属性来调用WindowsIdentity来实现实际的模拟。

  列表1:在SQLCLR代码中使用模拟

try
{
 //模拟当前SQL安全上下文
 WindowsIdentity CallerIdentity = SqlContext.WindowsIdentity;
 if (CallerIdentity != null)
 {
  OriginalContext = CallerIdentity.Impersonate();
  //做一些保护操作
 }
}
catch
{
 //从存取问题中恢复
}
finally
{
 if (OriginalContext != null)
  OriginalContext.Undo();
}

  列表1向你展示如何在SQLCLR代码中使用模拟。WindowsImpersonationContext对象属于System.Security.Principal命名空间的一部分并且描述了在你模拟前的Windows用户安全上下文。SqlContext对象属于和sql server(WINDOWS平台上强大的数据库平台)一起安装的Microsoft.sql server(WINDOWS平台上强大的数据库平台).Server命名空间的一部分并且提供在sql server(WINDOWS平台上强大的数据库平台)主机和SQLCLR代码之间的一个钩子。在这种情况中,它使用WindowsIdentity属性来得到当前安全身份的一个令牌。这是Windows登录的安全上下文-该代码在这一登录下运行。该代码测试是否结果CallerIdentity为null,如果该代码在一种SQL登录下运行时它将为null。最后,它调用WindowsIdentity模拟来实现实际的模拟,并保存原始的上下文以用于当要求恢复到该上下文时。

  必须理解,仅当执行需要保护的操作(例如打开一文件)时模拟才起作用。一旦它被打开,该代码就不再需要模拟。因此,一旦你完成保护的操作,即恢复回去。

  最后,通过调用OriginalContext的Undo方法,代码块负责恢复到原始上下文。如果你在函数结束之前不进行恢复,那么sql server(WINDOWS平台上强大的数据库平台)将引发一个异常。

  对于模拟也存在一些限制。当该模拟起作用时,你就无法再使用sql server(WINDOWS平台上强大的数据库平台)实例存取数据或对象。在你再次存取本地数据之前,你必须恢复模拟。这也意味着,进程内数据存取总是发生在会话的当前安全上下文中。

  有趣的是,一个异步执行的UNSAFE程序集(也就是说,它能够创建线程并且异步地运行代码)永远不会允许进程内数据存取。其实,这并不是一个安全问题而显然是一个可靠性的问题。

  三、 可信赖的数据库

  在SAFE程序集和其它权限设置级别之间的另外一个区别是在sql server(WINDOWS平台上强大的数据库平台) 2005测试期添加的。现在,你必须满足两个要求之一来创建EXTERNAL_ACCESS或UNSAFE程序集:

  · 数据库所有者(dbo)必须拥有EXTERNAL ACCESS ASSEMBLY权限并且数据库必须拥有TRUSTWORTHY属性集。

  或者:

  · 程序集的使用方式必须是,通过一个具有EXTERNAL ACCESS ASSEMBLY权限的登录而且要使用一个证书或一个非对称密钥。

  EXTERNAL ACCESS ASSEMBLY权限是另一种新的粒度许可权-允许一名负责人创建这类程序集。默认情况下,系统管理员拥有它并且能够把它赋给其它登录。但是这样做时要慎重,这当然因为可能潜在地允许危险代码安装到服务器中。

  一个数据库的TRUSTWORTHY属性要求设置管理员权限并且是在数据库中安装非SAFE程序集的前提。基于EXTERNAL ACCESS ASSEMBLY权限,一个DBA能够控制是否存在潜在危险性的程序集能够被安装到任何数据库中,以及谁能够把它们放到那里。这很有希望会使DBA安心而不必再担心他们的服务器会感染.NET代码!

Tags:SQL ServerSQLCLR 代码

编辑录入:coldstar [复制链接] [打 印]
赞助商链接