1

这已经困扰我2天了。我有一个需要EXTERNAL_ACCESS 的CLR sp。我可以通过将 TRUSTWORTHY ON 设置为通过 VS2010 在我的开发盒上部署它,但我们不想对生产服务器这样做。我们购买了与 AuthentiCode 兼容的证书,我尝试用它签署我的程序集,但由于链接而失败,所以我按照此处详述的说明从证书中删除链接

接下来,我尝试在 VS 中对程序集进行签名,但收到错误“尝试引用不存在的令牌”。

因此,正如几位博主推荐的那样,转到命令行并使用 SignTool.exe 使用去链证书对程序集进行签名。该实用程序报告签名成功。

现在将程序集导入我的开发盒上的 SQL Server(express 2008R2)。首先将 TRUSTWORTHY 设置为关闭,因为此过程必须应用于生产服务器。然后我跑

   CREATE ASSEMBLY SqlClrProcedures from 'c:\<snip>\SqlClrProcedures.dll'
   WITH PERMISSION_SET = EXTERNAL_ACCESS

这会出现以下错误:*为程序集“SqlClrProcedures”创建程序集失败,因为程序集“SqlClrProcedures”未获得 PERMISSION_SET = EXTERNAL_ACCESS 的授权。当以下任一情况为真时,程序集被授权:数据库所有者 (DBO) 具有 EXTERNAL ACCESS ASSEMBLY 权限并且数据库具有 TRUSTWORTHY 数据库属性;或程序集使用证书或非对称密钥签名,该证书或非对称密钥具有相应的登录名并具有外部访问程序集权限。*

我以 sa 身份登录。好的,所以我创建了一个用户,将数据库的所有权分配给他并授予他外部访问权限:

GRANT EXTERNAL ACCESS Assembly to ClrLogin

然后尝试

CREATE ASSEMBLY SqlClrProcedures AUTHORIZATION ClrLogin from 'c:\<snip>\SqlClrProcedures.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS

这会产生与上述相同的错误。

dbo 已被授予 EXTERNAL ACCESS ASSEMBLY 并且程序集已签名,但我不了解有关相应登录的部分,我需要登录证书吗?

如果设置 TRUSTWORTHY ON 只是为了通过 CREATE ASSEMBLY 程序集导入正常但是当我运行 sp 时出现此错误:

An error occurred in the Microsoft .NET Framework while trying to load assembly id 65573. The server may be running out of resources, or the assembly may not be trusted with PERMISSION_SET = EXTERNAL_ACCESS or UNSAFE. Run the query again, or check documentation to see how to solve the assembly trust issues. For more information about this error: 
System.IO.FileLoadException: Could not load file or assembly 'sqlclrprocedures, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)
System.IO.FileLoadException: 
   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)

所以看来证书没有得到认可。有人可以告诉我我做错了什么吗?

4

2 回答 2

1

Kent Tegels 提供了一个分步示例,展示了使用证书对 clr 程序集进行签名的安全过程,然后将证书加载到服务器中,从而使程序集被认为是可信的。

于 2011-08-26T14:35:28.890 回答
1
  1. 正确,TRUSTWORTHY 应该设置为OFF。有关更多信息,请参阅我的帖子:请,请,请停止使用模拟、可信和跨数据库所有权链接

  2. 在 Visual Studio 中签署程序集意味着应用强名称密钥;它不允许使用证书签名(很不幸)。

  3. 由于您将使用已签名的程序集,因此您不必担心数据库所有者 (dbo) 被链接到已被授予EXTERNAL ACCESS ASSEMBLYorUNSAFE ASSEMBLY权限的登录名(错误消息表明 dbo 的权限仅在TRUSTWORTHYis时才重要ON) . 使用签名程序集时,将授予从非对称密钥或证书(用于对程序集签名)创建的登录名EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY权限。

  4. 不需要AUTHORIZATION ClrLogin零件_

  5. 您需要(或需要)做的是:

    1. master在数据库中创建证书。您可以通过几种不同的方式创建证书:

      • 一个已经加载的SAFE程序集(这将是FROM ASSEMBLY选项)。但是,由于 SQL Server 2017 中引入的更改,这不再是一种选择。
      • 来自文件系统的.cer文件(即公钥)(这是FROM FILE选项)
      • 文件系统中的.dll文件(这是FROM EXECUTABLE FILE选项)
      • .cer文件直接来自VARBINARY文字(这是选项FROM BINARY)。要轻松将该文件转换为十六进制字节字符串(即0x12AB00003D...),您可以使用我编写的开源BinaryFormatter命令行实用程序,该实用程序可用于自动化/持续集成(通过将其转换为要导入/包含的文件) ,或用于手动编写CREATE CERTIFICATE语句脚本(通过将其直接转换到剪贴板以粘贴到脚本中)。
    2. 从该证书创建登录
    3. 授予该登录权限EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY权限(从 SQL Server 2017 开始,仅UNSAFE ASSEMBLY授予权限)。

关于 SQL Server 2017

SQL Server 2017 引入了一项新的安全功能(“CLR 严格安全”,一个高级选项),该功能默认启用,并要求所有程序集,即使是那些标记为 的程序SAFE集,都使用非对称密钥(即强名称)或证书进行签名,并且有一个具有UNSAFE ASSEMBLY权限的登录名(基于用于签署大会的任何内容) 。有关如何使用或不使用 Visual Studio / SSDT 的详细信息,请参阅我的以下两篇文章:

请避免使用新的可信程序集“功能”,因为它的缺陷多于好处,更不用说它完全没有必要,因为现有功能已经处理了“可信程序集”旨在解决的情况。有关这方面的完整详细信息以及处理现有未签名程序集的正确方法的演示,请参阅:SQLCLR 与 SQL Server 2017,第 4 部分:“受信任的程序集” - 失望

于 2018-03-16T02:44:56.370 回答