我正在尝试按照https://sqlquantumleap.com/2017/08/09/sqlclr-vs-sql-server-2017-part-2-clr-strict-security-solution-1/中所述的步骤在SQL Server 2017 DB中部署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创建了完整的repro解决方案。我可以按照此处描述的整个过程(自述文件)进行操作,直到必须将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 Server接受我的CLR而不会降低严格的安全性。

显然我遗漏了一些东西,但是我不确定棘手的过程的许多细节,因此这将是一个艰难的猜测。谁能建议我们该程序出了什么问题,以便我们可以快速而又逐步地了解如何在SQL Server中插入CLR程序集?对于最新版本,这个简单的任务似乎变得非常困难。

最佳答案

根据我在GitHub存储库中看到的内容,似乎跳过了一些步骤:


您未在原始SQL2017_KeyAsm项目上设置密码。这就是为什么它仍然是.snk文件(即SQL2017_KeyAsm.snk)而不是.pfx文件(即SQL2017_KeyAsm.pfx)的原因。我猜想您取消选中了“使用密码保护我的密钥文件”复选框(我认为默认情况下它已选中),因为您根本不需要.snk。此外,在您的SQL2017_KeyAsm.sqlproj文件中,您当前具有:

<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.snk</AssemblyOriginatorKeyFile>


什么时候应该具备以下条件:

<AssemblyOriginatorKeyFile>SQL2017_KeyAsm.pfx</AssemblyOriginatorKeyFile>


虽然,自述文件中的说明是正确的,但正如您在此处所述:“输入密码”。不过,这可能可以解释您遇到的密码错误,因为没有保护私钥的密码。要么是因为密码错误,要么是由于使用了错误的pfx文件(参见下文)。我想先尝试修复以下各项,因为使用无密码的SNK可能可以摆脱,我只是从未尝试过。
在“一次性程序”部分的结尾,在以“最后,以下步骤...”开头的段落之后的最后两个步骤中,步骤2使用了错误的.pfx文件。我猜测这是在上一步中没有.pfx文件的直接结果(由于未设置密码),因此您抓取了那里唯一的.pfx文件。这就是为什么在尝试加载SqlServerUdf程序集时出现错误的原因:您使用证书对程序集进行了签名,但是该证书仅用作将KeyAsm程序集加载到[master]的机制,以便可以提取非对称密钥从中。之后,将删除证书。非对称密钥是.snk文件的公共密钥,当您告诉Visual Studio希望对SQL2017_KeyAsm项目进行签名时,该文件即已创建。因此,在告诉Visual Studio签名SqlServerUdf项目时,需要选择.snk文件(如果使用密码保护,则为.pfx)。这样做将使用相同的私钥对两个项目/程序集进行签名。


因此,首先要做的是更改用于签名SqlServerUdf程序集的私钥。它不应是证书.pfx文件。它必须与用于签署KeyAsm文件的密钥相同。在您的情况下,这将是SQL2017_KeyAsm.snk。

尝试进行一项更改,看看是否一切正常。如果不是,请返回并向snk文件添加密码(通过Visual Studio)。您不需要重新生成证书或其.pfx文件,因为公钥应该保持不变,并且无论如何,这就是加载到[master]中的全部内容。但是,请让我知道这是否仍然无效。同时,我将更新该帖子,以更明确地说明密码以及何时使用哪个pfx文件。

关于c# - 在SQL Server 2017中部署CLR UDF:过程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55399532/

10-11 08:32