Sql-Server
在不啟用 TRUSTWORTHY 的情況下創建組件 System.DirectoryServices.AccountManagement.dll
首先,這是針對 SQL Server 2016 的。如果我使用的是 2017+,我會使用
sp_add_trusted_assembly
. 只是想在問問題之前澄清這一點。如何在不使用的情況下註冊程序集System.DirectoryServices.AccountManagement.dll
TRUSTWORTHY 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 中)。
還:
- 假設它們被主程序引用,您不必添加/刪除比主程序集更多的內容。通過 DLL 添加程序集(而不是十六進製字節/
VARBINARY
文字)時,SQL Server 將抓取同一文件夾中的任何引用程序集。它將所有這些自動添加的程序集設置為“可見 = 0”。如果主程序集被刪除,設置為“可見 = 0”且由主程序集引用的程序集將自動刪除。- 您無需為基於簽名的登錄同時授予
UNSAFE ASSEMBLY
和EXTERNAL ACCESS ASSEMBLY
權限。UNSAFE ASSEMBLY
權限假定權限,如果您有權限EXTERNAL ACCESS ASSEMBLY
,您可以將程序集設置為任一。PERMISSION_SET``UNSAFE ASSEMBLY
- 如果使用 SQL Server 2017 或更高版本,則無需使用“受信任的程序集”功能。請在此處查看我的文章,了解為什麼以及應該做什麼:SQLCLR 與 SQL Server 2017,第 1 部分:“CLR 嚴格安全”-問題。當然,在這種特殊情況下,這是一個有爭議的問題,因為正確的方法是使用上述證書方法。
請注意,在類似問題的其他答案中,無論是我自己還是其他人回答,答案始終是
TRUSTWORTHY
必須啟用的。這是由於我最近才意識到的 Microsoft 文件提供的錯誤資訊。我正在糾正我以前的答案和該文件。