我在C#CLR代码中使用.NET DirectoryServices和DirectoryServices.AccountManagement。我想作为不安全的CLR存储过程发布到我的SQL Server数据库。在Visual Studio中,我签署了我的CLR项目。我想避免转向值得信赖。我如何签署组件? 我知道这听起来很简单,但我在google上搜索了4个小时而没有得到答案。当我将Stairway下载到CLR时,我认为我非常接近,但是在那里找不到答案。
答案 0 :(得分:3)
首先:感谢您不使用简单路线并启用TRUSTWORTHY
。认真。正确地做这件事并不是那么多工作,所以我(和你的雇主)感谢你做更多的研究,当你无法做得更远时,伸出援助之手。
如果您指的是SQL Server Central上的“Stairway to SQLCLR”系列,那么我就是这些文章的作者。如果不容易理解这些信息,我很抱歉。我将概述这里的步骤:
根据您的工作和总体要求,您可以在此处选择一些选项:
[master]
,标记为{{ 1}},从中创建非对称密钥(这里不执行代码,因此不需要在此处标记为SAFE
)。UNSAFE
时创建),那么我发现最好创建一个单独的空程序集,也使用相同的强名称密钥文件进行签名(即用于主程序集的UNSAFE
文件)。然后我将那个空的但已签名的装配加载到.pfx
,标记为[master]
在SAFE
中创建的程序集使用用于签署主[master]
程序集的相同.pfx
文件进行签名后,您只需创建,在UNSAFE
中,来自该大会的非对称密钥。
从该非对称密钥创建登录
授予基于密钥的登录[master]
权限
这些步骤适用于SQL Server 2005 - 2016,我在Stairway to SQLCLR Level 7: Development and Security文章中提供了有关如何自动执行此操作的说明(上面的选项2 - 使用单独的,空的,已签名的程序集)。 (顺便说一下,我确实认识到第7级中描述的步骤确实有点多,但是它们确实提供了使用Visual Studio的自动化方法,并且可以通过使用T4模板来简化它们 - 它随VS一起提供 - 但是我的避风港还没有时间写出简化的方法 - 希望很快就会这么做。)
但是,如果您需要考虑SQL Server 2017(或者更新,可能),那么上述步骤将无法正常工作UNSAFE ASSEMBLY
可以再创建程序集而无需签名并具有相应的签名基于SAFE
权限的登录。而且,遗憾的是,UNSAFE ASSEMBLY
不允许从十六进制字节字符串/ CREATE ASYMMETRIC KEY
文字创建,因此您需要使用允许以这种方式创建的证书。在这些方面,我有两个博客文章,详细,一步一步,如何实现这一点,通过Visual Studio完全自动化(甚至不使用Visual Studio):
无论你做什么,不都会被SQL Server 2017的新“受信任的程序集”功能所迷惑,因为它有很多问题,如下所述:SQLCLR vs. SQL Server 2017, Part 4: “Trusted Assemblies” – The Disappointment和一个我正在研究的更多帖子。
为了帮助改善这种不必要的痛苦过程,请支持我的改进请求以改进VARBINARY
和SSDT:
答案 1 :(得分:1)
我们有几个需要它的旧项目。直到本周我花时间搞清楚这一点,我们一直在使用可怕的可信赖旗帜。
经过一系列的研究,我能够通过在我的Visual Studio项目中使用预部署sql脚本和一些一次性设置来将其设置为相当轻松。 This article对我帮助最大。
我已经测试并证实了这项工作:
步骤:
使用Visual Studio的Developer命令提示符创建一个新的强名称密钥,然后输入:
sn -k ".\CLRKey.snk"
在Visual Studio项目设置的SQLCLR区域中,单击“签名”按钮,然后选择通过浏览到刚刚创建的密钥文件对程序集进行签名:
将CLRKey.snk
复制到每个目标SQL Server的C:\
,或者服务器可以读取的其他路径。
将此预部署脚本添加到Visual Studio项目中,调整密钥路径和密码以适合您的环境:
DECLARE @sp nvarchar(255) = '$(DatabaseName)..sp_executesql';
DECLARE @create_user nvarchar(4000) = N'CREATE USER [CLRExtensionLogin] FOR LOGIN [CLRExtensionLogin]'
DECLARE @MSG varchar(8000)
use master;
BEGIN TRY
BEGIN TRAN
IF NOT EXISTS (select 1 from sys.asymmetric_keys where name=N'CLRExtensionKey') BEGIN
create asymmetric key CLRExtensionKey
from file = 'c:\CLRKey.snk'
encryption by password = '<invent a password>'
RAISERROR( 'Key created.', 0, 1 ) WITH NOWAIT
END ELSE BEGIN
RAISERROR( 'Key exists.', 0, 1 ) WITH NOWAIT
END
IF NOT EXISTS (SELECT * FROM sys.syslogins WHERE name=N'CLRExtensionLogin') BEGIN
CREATE LOGIN CLRExtensionLogin FROM ASYMMETRIC KEY CLRExtensionKey;
EXEC @sp @create_user
RAISERROR( 'User created.', 0, 1 ) WITH NOWAIT
END ELSE BEGIN
RAISERROR( 'User exists.', 0, 1 ) WITH NOWAIT
END
GRANT EXTERNAL ACCESS ASSEMBLY, UNSAFE ASSEMBLY TO [CLRExtensionLogin];
COMMIT TRAN
SET @MSG = 'Assembly access granted.' + CHAR(10) + 'Done.'
RAISERROR( @MSG, 0, 1 ) WITH NOWAIT
END TRY
BEGIN CATCH
SET @MSG = ERROR_MESSAGE() + CHAR(10) + 'Aborted.'
RAISERROR( @MSG, 16, 1 )
IF @@TRANCOUNT > 0 ROLLBACK
END CATCH
USE [$(DatabaseName)];
只要SQL Server可以在脚本第一次运行时读入该密钥文件,您就可以自由发布到同一服务器,而不必再担心所有这些。
如果您有其他项目发布到同一服务器,您所要做的就是使用与步骤2中相同的密钥对其进行签名,但最佳做法是链接到同一个预部署脚本在所有项目中,以防您希望在某个时刻将其中一个发布到不同的服务器。希望这有帮助!