这已经困扰了我2天了。我有一个需要EXTERNAL_ACCESS的CLR sp。我可以通过设置TRUSTWORTHY ON在我的开发盒上通过VS2010进行部署,但我们不想对生产服务器这样做。我们购买了一个与AuthentiCode兼容的证书,我试图用它签署我的程序集,但由于链接失败,所以我按照说明detailed here to strip out chaining from the cert。
接下来我尝试在VS中签署程序集,但收到错误“尝试引用不存在的令牌。”
所以转到命令行并使用SignTool.exe使用解链证书签署程序集,正如几位博客建议的那样。该实用程序报告签名成功。
现在在我的开发框中将程序集导入SQL Server(表达2008R2)。首先设置TRUSTWORTHY,因为此过程必须应用于生产服务器。然后我跑
CREATE ASSEMBLY SqlClrProcedures from 'c:\<snip>\SqlClrProcedures.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS
这会出现以下错误:*程序集“SqlClrProcedures”的CREATE ASSEMBLY失败,因为程序集“SqlClrProcedures”未获得PERMISSION_SET = EXTERNAL_ACCESS的授权。如果满足以下任一条件,则授权程序集:数据库所有者(DBO)具有EXTERNAL ACCESS ASSEMBLY权限,并且数据库具有TRUSTWORTHY数据库属性;或者使用具有EXTERNAL ACCESS ASSEMBLY权限的相应登录的证书或非对称密钥对程序集进行签名。*
我是以sa身份登录的。好的,我创建了一个用户,为他分配了db的所有权并授予他EXTERNAL ACCESS:
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)
所以看来证书没有得到认可。有人可以告诉我我做错了吗?
答案 0 :(得分:1)
Kent Tegels有一步一步example显示了使用证书对clr程序集进行签名的安全过程,然后将证书加载到服务器中,以便将程序集视为可信任。
答案 1 :(得分:0)
正确,TRUSTWORTHY
应设置为OFF
。有关详细信息,请参阅我的帖子:PLEASE, Please, please Stop Using Impersonation, TRUSTWORTHY, and Cross-DB Ownership Chaining
在Visual Studio中签署程序集意味着应用强名称密钥; 不允许签署证书(非常不幸)。
由于您将使用已签名的程序集,因此您无需担心数据库所有者(dbo)被链接到已授予EXTERNAL ACCESS ASSEMBLY
或{{1}的登录名}权限(错误消息表明dbo的权限仅在UNSAFE ASSEMBLY
为TRUSTWORTHY
时才有效)。使用已签名的程序集时,从非对称密钥或证书(用于签署程序集)创建的登录名将被授予ON
或EXTERNAL ACCESS ASSEMBLY
权限。
您不需要 UNSAFE ASSEMBLY
部分
您需要(或需要)做的是:
在AUTHORIZATION ClrLogin
数据库中创建证书。您可以通过几种不同的方式创建证书:
master
程序集(这将是SAFE
选项)。但是,多亏了SQL Server 2017中引入的更改,这已不再是一个选项。FROM ASSEMBLY
选项)FROM FILE
选项)FROM EXECUTABLE FILE
字面值的 .cer 文件(这将是VARBINARY
选项)。要轻松地将该文件转换为十六进制字节字符串(即FROM BINARY
),您可以使用我编写的开源BinaryFormatter命令行实用程序,该实用程序可用于自动化/持续集成(通过转换它)进入要导入/包含的文件),或用于手动编写0x12AB00003D...
语句脚本(通过将其直接转换为要粘贴到脚本中的剪贴板)。CREATE CERTIFICATE
或EXTERNAL ACCESS ASSEMBLY
权限(从SQL Server 2017开始,只有UNSAFE ASSEMBLY
权限)。 SQL Server 2017引入了一项新的安全功能(&#34; CLR严格安全性&#34;,一种高级选项),默认情况下已启用,并要求所有程序集(即使标记为UNSAFE ASSEMBLY
的程序集)都必须签名使用非对称密钥(即强名称)或证书,并具有SAFE
权限的登录(基于用于签署程序集的任何内容)。有关如何使用Visual Studio / SSDT的详细信息,请参阅以下两篇帖子:
请避免使用新的受信任程序集&#34;功能&#34;因为它有更多的缺陷而不是好处,更不用说它首先是完全没有必要的,因为现有的功能已经处理了这种情况&#34; Trusted Assemblies&#34;本来打算解决。有关该内容的完整详细信息以及处理现有未签名大会的正确方法的演示,请参阅:SQLCLR vs. SQL Server 2017, Part 4: “Trusted Assemblies” – The Disappointment。