在 SQL Server 2017 中部署 CLR UDF:过程
Deploy CLR UDF in SQL Server 2017: procedure
我正尝试按照 https://sqlquantumleap.com/2017/08/09/sqlclr-vs-sql-server-2017-part-2-clr-strict-security-solution-1/ 中描述的过程在 SQL Server 2017 数据库中部署 CLR 程序集。基本上,出于测试目的,我只包含一个包含几个基于 Regex 的函数的程序集:
public class TextUdf
{
[SqlFunction(Name = "RegexIsMatch", IsDeterministic = true, IsPrecise = true)]
public static SqlBoolean RegexIsMatch(SqlString text, SqlString pattern,
SqlInt32 options)
{
if (text.IsNull) return SqlBoolean.Null;
if (pattern.IsNull) pattern = "";
return Regex.IsMatch((string)text,
(string)pattern,
options.IsNull? RegexOptions.None : (RegexOptions)options.Value,
new TimeSpan(0, 0, 10))
? SqlBoolean.True
: SqlBoolean.False;
}
[SqlFunction(Name = "RegexReplace", IsDeterministic = true, IsPrecise = true)]
public static SqlString RegexReplace(SqlString text, SqlString pattern,
SqlString replacement, SqlInt32 options)
{
if (text.IsNull || pattern.IsNull) return text;
return Regex.Replace((string)text, (string)pattern,
(string)replacement,
options.IsNull ? RegexOptions.None : (RegexOptions)options.Value);
}
}
我在 https://github.com/Myrmex/sqlclr 上创建了一个完整的重现解决方案。我可以遵循那里描述的整个过程(自述文件),直到我必须将 PFX 证书分配给要部署的 CLR 程序集。此时,我收到此错误:
MSB3325: Cannot import the following key file: pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: ...
按照错误信息的指导,我发现我可以通过安装带有sn
的PFX来解决这个问题,这样我就可以在提示时手动输入密码(参见Cannot import the keyfile 'blah.pfx' - error 'The keyfile may be password protected')。
完成此操作后,我可以使用 UDF 函数编译我的 CLR 程序集。现在,当我尝试通过 CREATE ASSEMBLY [SqlServerUdf] FROM 0x...binary stuff...
在测试数据库(只是为此目的创建的一个空数据库)中安装它时,我收到此错误:
CREATE or ALTER ASSEMBLY for assembly 'SqlServerUdf' with the SAFE or EXTERNAL_ACCESS option failed because the 'clr strict security' option of sp_configure is set to 1. Microsoft recommends that you sign the assembly with a certificate or asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission. Alternatively, you can trust the assembly using sp_add_trusted_assembly.
这违背了我必须遵循的冗长程序的目的,以便让 SQL 服务器接受我的 CLR 而不会降低严格的安全性。
显然我遗漏了一些东西,但我不确定这个棘手过程的许多细节,所以这将是一个艰难的猜测。任何人都可以建议我们该过程有什么问题,以便我们可以快速、详细地逐步参考如何在 SQL 服务器中插入 CLR 程序集?这个简单的任务在最新版本中似乎变得非常困难...
根据我在 GitHub 存储库中看到的内容,您似乎跳过了一些步骤:
您没有为原始 SQL2017_KeyAsm 项目设置密码。这就是为什么它仍然是 .snk 文件(即 SQL2017_KeyAsm.snk)而不是 .pfx 文件(即 SQL2017_KeyAsm.pfx)。我猜你 un 选中了 "Protect my key file with a password" 复选框(我认为它是默认选中的),因为你不应该 .snk 完全没有。此外,在您的 SQL2017_KeyAsm.sqlproj 文件中,您当前拥有:
<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.snk</AssemblyOriginatorKeyFile>
当你应该具备以下条件时:
<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.pfx</AssemblyOriginatorKeyFile>
尽管如此,您在自述文件中的说明是正确的,正如您在此处所述:"enter in a password"。不过,这可能解释了您遇到的密码错误,因为没有密码保护私钥。要么,要么密码错误是由于使用了错误的 pfx 文件(见下文)。我想首先尝试修复以下项目,因为它 可能 可以通过无密码 SNK 逃脱,我从来没有尝试过。
在 一次性程序 部分的末尾,在以 "Finally, the following steps..." 开头的段落之后的最后两个步骤中,步骤2 使用了错误的 .pfx 文件。我猜这是上一步没有 .pfx 文件的直接结果(由于没有设置密码),所以你抓取了唯一的 。 pfx 文件。 这 就是您在尝试加载 SqlServerUdf 程序集时遇到错误的原因:您使用 certificate[= 签署了程序集63=],但该证书仅用作将 KeyAsm 程序集加载到 [master]
的机制,以便可以从中提取非对称密钥。之后证书被丢弃。非对称密钥是 .snk 文件的 public 密钥,当您告诉 Visual Studio 您想要 SQL2017_KeyAsm 项目签署。因此 .snk 文件(或 .pfx 如果你用密码保护它)是你需要 select 当你告诉 Visual Studio 签署 SqlServerUdf 项目。这样做将使用相同的私钥对两个项目/程序集进行签名。
因此,首先要做的是更改用于签署 SqlServerUdf 程序集的私钥。应该不是证书.pfx文件。它需要与用于签署 KeyAsm 文件的密钥相同。在您的情况下,这将是 SQL2017_KeyAsm.snk.
尝试进行一项更改,看看是否一切正常。如果没有,则返回并在 snk 文件中添加密码(通过 Visual Studio)。您不需要重新生成证书或其 .pfx 文件,因为 public 密钥应该保持不变,这就是加载到 [master]
无论如何。但是,如果这仍然不起作用,请告诉我。同时,我将更新 post 以更明确地说明密码,以及何时使用哪个 pfx 文件。
我正尝试按照 https://sqlquantumleap.com/2017/08/09/sqlclr-vs-sql-server-2017-part-2-clr-strict-security-solution-1/ 中描述的过程在 SQL Server 2017 数据库中部署 CLR 程序集。基本上,出于测试目的,我只包含一个包含几个基于 Regex 的函数的程序集:
public class TextUdf
{
[SqlFunction(Name = "RegexIsMatch", IsDeterministic = true, IsPrecise = true)]
public static SqlBoolean RegexIsMatch(SqlString text, SqlString pattern,
SqlInt32 options)
{
if (text.IsNull) return SqlBoolean.Null;
if (pattern.IsNull) pattern = "";
return Regex.IsMatch((string)text,
(string)pattern,
options.IsNull? RegexOptions.None : (RegexOptions)options.Value,
new TimeSpan(0, 0, 10))
? SqlBoolean.True
: SqlBoolean.False;
}
[SqlFunction(Name = "RegexReplace", IsDeterministic = true, IsPrecise = true)]
public static SqlString RegexReplace(SqlString text, SqlString pattern,
SqlString replacement, SqlInt32 options)
{
if (text.IsNull || pattern.IsNull) return text;
return Regex.Replace((string)text, (string)pattern,
(string)replacement,
options.IsNull ? RegexOptions.None : (RegexOptions)options.Value);
}
}
我在 https://github.com/Myrmex/sqlclr 上创建了一个完整的重现解决方案。我可以遵循那里描述的整个过程(自述文件),直到我必须将 PFX 证书分配给要部署的 CLR 程序集。此时,我收到此错误:
MSB3325: Cannot import the following key file: pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: ...
按照错误信息的指导,我发现我可以通过安装带有sn
的PFX来解决这个问题,这样我就可以在提示时手动输入密码(参见Cannot import the keyfile 'blah.pfx' - error 'The keyfile may be password protected')。
完成此操作后,我可以使用 UDF 函数编译我的 CLR 程序集。现在,当我尝试通过 CREATE ASSEMBLY [SqlServerUdf] FROM 0x...binary stuff...
在测试数据库(只是为此目的创建的一个空数据库)中安装它时,我收到此错误:
CREATE or ALTER ASSEMBLY for assembly 'SqlServerUdf' with the SAFE or EXTERNAL_ACCESS option failed because the 'clr strict security' option of sp_configure is set to 1. Microsoft recommends that you sign the assembly with a certificate or asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission. Alternatively, you can trust the assembly using sp_add_trusted_assembly.
这违背了我必须遵循的冗长程序的目的,以便让 SQL 服务器接受我的 CLR 而不会降低严格的安全性。
显然我遗漏了一些东西,但我不确定这个棘手过程的许多细节,所以这将是一个艰难的猜测。任何人都可以建议我们该过程有什么问题,以便我们可以快速、详细地逐步参考如何在 SQL 服务器中插入 CLR 程序集?这个简单的任务在最新版本中似乎变得非常困难...
根据我在 GitHub 存储库中看到的内容,您似乎跳过了一些步骤:
您没有为原始 SQL2017_KeyAsm 项目设置密码。这就是为什么它仍然是 .snk 文件(即 SQL2017_KeyAsm.snk)而不是 .pfx 文件(即 SQL2017_KeyAsm.pfx)。我猜你 un 选中了 "Protect my key file with a password" 复选框(我认为它是默认选中的),因为你不应该 .snk 完全没有。此外,在您的 SQL2017_KeyAsm.sqlproj 文件中,您当前拥有:
<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.snk</AssemblyOriginatorKeyFile>
当你应该具备以下条件时:
<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.pfx</AssemblyOriginatorKeyFile>
尽管如此,您在自述文件中的说明是正确的,正如您在此处所述:"enter in a password"。不过,这可能解释了您遇到的密码错误,因为没有密码保护私钥。要么,要么密码错误是由于使用了错误的 pfx 文件(见下文)。我想首先尝试修复以下项目,因为它 可能 可以通过无密码 SNK 逃脱,我从来没有尝试过。
在 一次性程序 部分的末尾,在以 "Finally, the following steps..." 开头的段落之后的最后两个步骤中,步骤2 使用了错误的 .pfx 文件。我猜这是上一步没有 .pfx 文件的直接结果(由于没有设置密码),所以你抓取了唯一的 。 pfx 文件。 这 就是您在尝试加载 SqlServerUdf 程序集时遇到错误的原因:您使用 certificate[= 签署了程序集63=],但该证书仅用作将 KeyAsm 程序集加载到
[master]
的机制,以便可以从中提取非对称密钥。之后证书被丢弃。非对称密钥是 .snk 文件的 public 密钥,当您告诉 Visual Studio 您想要 SQL2017_KeyAsm 项目签署。因此 .snk 文件(或 .pfx 如果你用密码保护它)是你需要 select 当你告诉 Visual Studio 签署 SqlServerUdf 项目。这样做将使用相同的私钥对两个项目/程序集进行签名。
因此,首先要做的是更改用于签署 SqlServerUdf 程序集的私钥。应该不是证书.pfx文件。它需要与用于签署 KeyAsm 文件的密钥相同。在您的情况下,这将是 SQL2017_KeyAsm.snk.
尝试进行一项更改,看看是否一切正常。如果没有,则返回并在 snk 文件中添加密码(通过 Visual Studio)。您不需要重新生成证书或其 .pfx 文件,因为 public 密钥应该保持不变,这就是加载到 [master]
无论如何。但是,如果这仍然不起作用,请告诉我。同时,我将更新 post 以更明确地说明密码,以及何时使用哪个 pfx 文件。