避免使用TRUSTWORTHY ON和PERMISSION_SET = UNSAFE,使用System.Net.Http

3
尝试使用CLR集成从我构建的DLL创建存储过程以便在SQL中使用。我认为我需要一个签名版本的System.Net.Http,下面将解释原因。欢迎提供任何建议或技巧。
如果我使用命令,则解决方案可完美运行。
ALTER DATABASE test2 SET TRUSTWORTHY ON

接着我使用以下命令创建程序集:

CREATE ASSEMBLY [System.Net.Http]
AUTHORIZATION dbo
FROM 'C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll'
WITH PERMISSION_SET = UNSAFE;
GO 

CREATE ASSEMBLY [CLRTest01]
AUTHORIZATION dbo
FROM 'C:\Windows\CLRTest01.dll'
WITH PERMISSION_SET = UNSAFE;
GO 

我选择相信默认设置,希望能够在不使用“UNSAFE”权限级别的情况下使用“SAFE”。然而,当我尝试对依赖于System.Net.Http的CLRTest01进行操作时,出现了System.Net.Http未签名或格式错误的问题。

CREATE ASSEMBLY [System.Net.Http]
AUTHORIZATION dbo
FROM 'C:\Windows\System.Net.Http.dll'
WITH PERMISSION_SET = SAFE;
GO 

使用v4.0_2.0.0.0__b03f5f7f11d50a3a时出错,因为现有策略将阻止安装程序集'System.Net.Http'的使用。使用v4.0_4.0.0.0__b03f5f7f11d50a3a时出错,因为在安全程序集'System.Net.Http'中的类型'System.Net.Http.HttpContent'具有静态字段'EncodingsWithBom'。安全程序集中静态字段的属性必须在Visual C#中标记为readonly,在Visual Basic中标记为ReadOnly,或在Visual C++和中间语言中标记为initonly。这让我相信我需要一个已签名的'System.Net.Http'版本。

你使用的是哪个版本的SQL Server?是否可以使用HttpWebRequest代替?这至少已经是SQL Server的CLR宿主的一部分了。此外,你可能应该从其原始位置添加程序集,而不是直接从GAC中添加。 - Solomon Rutzky
1个回答

4
所有.NET Framework库都已经签名。问题在于,您需要从用于签署该程序集的Strong Name Key(SNK)或Certificate(CER)的公钥中在[master]中创建一个Asymmetric Key或Certificate(通常情况下,程序集既被强命名又被证书签名)。
您可以执行以下操作来避免TRUSTWORTHY这是绝对正确的做法):
USE [master];

CREATE CERTIFICATE [MS.NETcer]
FROM EXECUTABLE FILE =
   'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Net.Http.dll';

CREATE LOGIN [MS.NETcer] FROM CERTIFICATE [MS.NETcer];

GRANT UNSAFE ASSEMBLY TO [MS.NETcer];

然后你可以这样做:
USE [SomeDatabase];

CREATE ASSEMBLY [System.Net.Http]
FROM 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Net.Http.dll'
WITH PERMISSION_SET = UNSAFE;

除此之外,由于您所发布的错误信息,您将无法使用PERMISSION_SET = SAFESystem.Net.Http一起使用。

安全程序集“System.Net.Http”中的类型“System.Net.Http.HttpContent”具有静态字段“EncodingsWithBom”。在安全程序集中,静态字段的属性必须在 Visual C# 中标记为 readonly,在 Visual Basic 中标记为 ReadOnly,在 Visual C++ 和中间语言中标记为 initonly。

由于您无法将该静态字段标记为readonly并重新编译,因此只能使用UNSAFE
有关一般SQLCLR工作的更多信息(包括有关设置Visual Studio以处理证书签名的说明,甚至包括在比以前版本更严格的SQL Server 2017中工作的信息):

SQLCLR.org


1
谢谢,这个方法让我成功安装了System.Net.Http。现在需要让依赖它的自定义DLL正常工作。 - LINQtothepast
@LINQtothepast 自定义 DLL 需要使用证书进行签名,将该证书的公钥(.cer 文件)加载到“master”数据库中,从该证书创建登录,并授予该登录“UNSAFE ASSEMBLY”权限。请访问 SQLCLR.org 了解如何执行此操作的链接,包括在 Visual Studio 中自动化操作(可以在该站点链接的我的博客或此处找到说明:SQLCLR vs. SQL Server 2017,Part 2:“CLR strict security” – Solution 1 或 Part 3)。 - Solomon Rutzky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接