sql-server - SQLCLR - 如何在不设置 TRUSTWORTHY ON 的情况下注册我的 CLR 程序集的引用程序集?

标签 sql-server sqlclr

我在注册我在 SQL CLR 程序集中使用的引用程序集时遇到问题。例如,我有一个名为 Something.dll 的 SQL CLR 程序集。此 Something.dll 引用 Newtonsoft.dll。

我签署 Something.dll,然后创建非对称 key 以使用 PERMISSION_SET = EXTERNAL_ACCESS 注册它。但是,我无法签署引用的程序集,因此 SQL Server 不允许我在未设置 TRUSTWORTHY ON 的情况下使用 UNSAFEEXTERNAL_ACCESS 权限注册它。

有没有办法在不设置 TRUSTWORTHY ON 的情况下注册 Newtonsoft.dll?

最佳答案

您可以使用您创建的证书对引用的程序集进行签名,在您尝试在 SQL Server 中创建程序集之前将该证书加载到 SQL Server 中,从该证书创建登录名,并授予该登录名所需的权限, EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY。事实上,为您自己的程序集使用相同的证书将允许它从 VARBINARY 文字/十六进制字节字符串加载,而不需要文件系统上的 DLL,这意味着该解决方案将仅适用在 SQL Server 2017 及更新版本中很好。

应该执行以下步骤:

  1. 通过命令提示符创建证书:

    MAKECERT -r -pe -n "CN=some name,O=your company,C=US" ^
    -e "12/31/2099" -sv private_key_file.pvk ^
    public_key_file.cer
    

    系统将通过模式弹出窗口提示您输入密码。你应该得到 2 个提示。两次使用相同的密码。

  2. 通过命令提示符将公钥和私钥文件合并到一个 PFX 文件中:

    PVK2PFX -pvk private_key_file.pvk -pi password ^
    -spc public_key_file.cer ^
    -pfx signing_certificate.pfx
    
  3. 通过命令提示符签署 DLL:

    signtool.EXE sign /v /p password ^
    /f signing_certificate.pfx ^
    NewtonSoft.dll
    
    signtool.EXE sign /v /p password ^
    /f signing_certificate.pfx ^
    MyProject.dll
    
  4. 将公钥转换为 VARBINARY 文字,以便它可以通过命令提示符(BinaryFormatter 是一个开放的)从 SQL 脚本创建,而不依赖于文件系统我编写的源实用程序,可在 GitHub 上获得,它将二进制文件转换为十六进制字节字符串,包括每行 80 个字符换行,这样您就没有一个愚蠢的长行):

    BinaryFormatter.exe public_key_file.cer ^
    create_certificate_script.sql 40
    
  5. 将每个 DLL 转换为 VARBINARY 文字,以便可以通过命令提示符从不依赖于文件系统的 SQL 脚本创建它:

    BinaryFormatter.exe Newtonsoft.DLL ^
    create_Newtonsoft_script.sql 40
    
    BinaryFormatter.exe MyProject.DLL ^
    create_MyProject_script.sql 40
    
  6. 在 SQL Server 中,创建证书、关联的登录名,并授予它所需的权限:

    USE [master];
    
    CREATE CERTIFICATE [MySqlclrStuff]
    FROM BINARY = 0x{contents_of_create_certificate_script.sql};
    
    CREATE LOGIN [MySqlclrStuff]
    FROM CERTIFICATE [MySqlclrStuff];
    
    GRANT UNSAFE ASSEMBLY TO [MySqlclrStuff];
    
  7. 在 SQL Server 中,在您的目标数据库中(不是在 master 中),创建两个程序集:

    USE [SomeDB];
    
    CREATE ASSEMBLY [Newtonsoft]
    FROM 0x{contents_of_create_Newtonsoft_script.sql}
    WITH PERMISSION_SET = UNSAFE;
    
    CREATE ASSEMBLY [MyProject]
    FROM 0x{contents_of_create_MyProject_script.sql}
    WITH PERMISSION_SET = UNSAFE;
    

如果您想知道如何在 Visual Studio/SSDT 中自动执行此操作,请参阅我的以下博客文章,其中详细介绍了如何执行此操作:

SQLCLR vs. SQL Server 2017, Part 3: “CLR strict security” – Solution 2

关于sql-server - SQLCLR - 如何在不设置 TRUSTWORTHY ON 的情况下注册我的 CLR 程序集的引用程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49801571/

相关文章:

c# - SQL 本地数据库未连接到其他计算机

sql-server - 适用于 Linux Docker 版本的 MSSQL Server

c# - .NET 正则表达式整个字符串匹配

c# - 如何在 VS 2013 中调试 CLR 存储过程

c# - 如何从数据库中获取 SQL CLR 函数的定义

c# - Entity Framework v4 - 来自链接服务器的简单存储过程 Select 语句(打开查询)返回 -1

sql-server - 如何加速 mssql_connect()

sql - 如何在 SQL Server Management Studio 中查看查询历史记录

sql-server - SQL 过程和 CLR 过程之间的区别?

sql-server - 将用户定义的 CLR 函数的执行限制为 sysadmin 而不是 dbowner