首先,这是针对 SQL Server 2016 的。如果我使用的是 2017+,我会使用sp_add_trusted_assembly
. 只是想在问这个问题之前澄清一下。
如何在不使用的情况下注册程序集System.DirectoryServices.AccountManagement.dllTRUSTWORTHY ON
?我无法使用从System.DirectoryServices.dll生成的非对称密钥让它工作。AccountManagement dll 的签名与System.DirectoryServices.dll不同。
我什至尝试从System.DirectoryServices.AccountManagement.dll创建一个单独的非对称密钥,但这会导致:
消息 15468,级别 16,状态 7,行 XXXXX
生成非对称密钥时出错。
这是我为尝试创建此程序集而编写的测试脚本。
USE master
IF DB_ID('CLR_Test') IS NULL BEGIN
CREATE DATABASE CLR_Test
END
GO
USE [CLR_Test]
GO
EXEC sp_configure @configname=clr_enabled, @configvalue=1
GO
RECONFIGURE
GO
/*************************************************************************************/
-- DROP OBJECTS IF FOUND FIRST
/*************************************************************************************/
-- DROP System.DirectoryServices.AccountManagement
IF EXISTS(SELECT 1 FROM sys.assemblies WHERE name = 'System.DirectoryServices.AccountManagement') BEGIN
RAISERROR( 'DROP ASSEMBLY [System.DirectoryServices.AccountManagement]', 0, 1) WITH NOWAIT
DROP ASSEMBLY [System.DirectoryServices.AccountManagement]
END
-- DROP System.DirectoryServices.Protocols
IF EXISTS(SELECT 1 FROM sys.assemblies WHERE name = 'System.DirectoryServices.Protocols') BEGIN
RAISERROR( 'DROP ASSEMBLY [System.DirectoryServices.Protocols]', 0, 1) WITH NOWAIT
DROP ASSEMBLY [System.DirectoryServices.Protocols]
END
-- DROP System.DirectoryServices
IF EXISTS(SELECT 1 FROM sys.assemblies WHERE name = 'System.DirectoryServices') BEGIN
RAISERROR( 'DROP ASSEMBLY [System.DirectoryServices]', 0, 1) WITH NOWAIT
DROP ASSEMBLY [System.DirectoryServices]
END
GO
IF EXISTS(SELECT 1 FROM sys.database_principals dp WHERE dp.name = 'MSFT_CLR_Login')
BEGIN
RAISERROR( 'DROP USER [MSFT_CLR_Login]', 0, 1) WITH NOWAIT
DROP USER [MSFT_CLR_Login]
END
GO
USE [master]
GO
IF (EXISTS(SELECT 1 FROM master.sys.syslogins WHERE name = 'MSFT_CLR_Login'))
BEGIN
RAISERROR( 'DROP LOGIN [MSFT_CLR_Login]', 0, 1) WITH NOWAIT
DROP LOGIN [MSFT_CLR_Login]
END
GO
IF (EXISTS(SELECT 1 FROM master.sys.asymmetric_keys WHERE name = 'MSFT_CLR_Key'))
BEGIN
--DROP ASYMMETRIC KEY [ClrKey]
RAISERROR( 'DROP ASYMMETRIC KEY [MSFT_CLR_Key]', 0, 1) WITH NOWAIT
DROP ASYMMETRIC KEY [MSFT_CLR_Key]
END
GO
/*************************************************************************************/
-- CREATE THE OBJECTS
/*************************************************************************************/
USE [master]
GO
IF (NOT EXISTS(SELECT 1 FROM master.sys.asymmetric_keys WHERE name = 'MSFT_CLR_Key'))
BEGIN
--DROP ASYMMETRIC KEY [ClrKey]
RAISERROR( 'CREATE ASYMMETRIC KEY [MSFT_CLR_Key]', 0, 1) WITH NOWAIT
CREATE ASYMMETRIC KEY [MSFT_CLR_Key]
FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.DirectoryServices.dll'
END
GO
IF (NOT EXISTS(SELECT 1 FROM master.sys.syslogins WHERE name = 'MSFT_CLR_Login'))
BEGIN
RAISERROR( 'CREATE LOGIN [MSFT_CLR_Login]', 0, 1) WITH NOWAIT
CREATE LOGIN [MSFT_CLR_Login] FROM ASYMMETRIC KEY [MSFT_CLR_Key]
END
GO
RAISERROR( 'GRANT UNSAFE ASSEMBLY', 0, 1) WITH NOWAIT
GRANT UNSAFE ASSEMBLY TO [MSFT_CLR_Login]
GO
RAISERROR( 'GRANT EXTERNAL ASSEMBLY', 0, 1) WITH NOWAIT
GRANT EXTERNAL ACCESS ASSEMBLY TO [MSFT_CLR_Login]
GO
USE CLR_Test
GO
IF NOT EXISTS(SELECT 1 FROM sys.database_principals dp WHERE dp.name = 'MSFT_CLR_Login')
BEGIN
RAISERROR( 'CREATE USER [MSFT_CLR_Login]', 0, 1) WITH NOWAIT
CREATE USER [MSFT_CLR_Login] FOR LOGIN [MSFT_CLR_Login]
END
GO
/*************************************************************************************/
-- CREATE THE CLR OBJECTS
/*************************************************************************************/
USE CLR_Test
GO
/****************************************************************************/
-- [System.DirectoryServices]
/****************************************************************************/
CREATE ASSEMBLY [System.DirectoryServices]
FROM 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.DirectoryServices.dll'
WITH PERMISSION_SET = UNSAFE
/****************************************************************************/
-- [System.DirectoryServices.Protocols]
/****************************************************************************/
CREATE ASSEMBLY [System.DirectoryServices.Protocols]
FROM 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.DirectoryServices.Protocols.dll'
WITH PERMISSION_SET = UNSAFE
/****************************************************************************/
-- [System.DirectoryServices.AccountManagement]
/****************************************************************************/
CREATE ASSEMBLY [System.DirectoryServices.AccountManagement]
FROM 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.DirectoryServices.AccountManagement.dll'
WITH PERMISSION_SET = UNSAFE
/*
-- NOR CAN YOU CREATE AN ASSYMETRIC KEY OFF System.DirectoryServices.AccountManagement.dll
CREATE ASYMMETRIC KEY [MSFT_SDA_CLR_Key]
FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.DirectoryServices.AccountManagement.dll'
-- results in:
-- Msg 15468, Level 16, State 7, Line 130
-- An error occurred during the generation of the asymmetric key.
*/
不,非对称密钥不起作用,很可能是因为强命名程序集在 .NET 4.5 或附近的某个地方发生了变化,现在是增强型强命名,SQL Server 的 CLR 主机不支持它(不是没有辞职,它不会在这里工作)。
关键是使用证书。从 DLL创建证书
master
,然后从该证书创建登录名,最后授予该UNSAFE ASSEMBLY
登录名的权限。应该就是这么简单(当然,假设 DLL 是纯 MSIL 而不是混合的,因为只有纯 MSIL 程序集才能加载到 SQL Server 中)。
还:
VARBINARY
文字)添加程序集时,SQL Server 将抓取同一文件夹中的所有引用程序集。它会将所有这些自动添加的程序集设置为“visible = 0”。如果主程序集被删除,则被主程序集引用的设置为“visible = 0”的程序集将被自动删除。UNSAFE ASSEMBLY
和EXTERNAL ACCESS ASSEMBLY
权限。该UNSAFE ASSEMBLY
权限假定该EXTERNAL ACCESS ASSEMBLY
权限,以便您可以将程序集设置为PERMISSION_SET
如果您有UNSAFE ASSEMBLY
权限。请注意,在类似问题的其他答案中,无论是我自己还是其他人回答,答案始终是
TRUSTWORTHY
必须启用的。这是由于 Microsoft 文档提供的错误信息,我直到最近才意识到这一点。我正在努力更正我之前的答案和该文档。这个答案是基于上面所罗门的建议。功劳都是他的。我按照他的建议重写了我的脚本,现在可以使用了!!!泰所罗门!我只是将它作为一个例子发布给其他追随我的人。