Sql Server 2019,遷移 clr 程序集,clr 嚴格安全
我們在 Sql Server 2008 伺服器上執行了一些舊程式碼,我們正在尋求升級到 Sql Server 2019。舊的 clr 程式碼真的很舊(就像 .net framework 2.0 old),所以我知道我必須重建新伺服器的程序集。我們從舊系統備份/恢復到新系統,雖然所有程序集都在那裡,但它們在執行時會拋出錯誤。
我遇到了“CLR strict security”文章,並且“使用 SAFE 或 EXTERNAL_ACCESS 選項為程序集 XXX 創建或更改程序集失敗,因為 sp_configure 的 ‘clr strict security’ 選項設置為 1。Microsoft 建議您使用證書…”消息。
我從第一個數據庫中的第一個程序集開始。我將框架更改為 4.6.1 並簽名。我首先嘗試了 ALTER ASSEMBLY,它說由於簽名差異而無法更改。所以我刪除了對該程序集的所有引用,然後刪除了該程序集,並使用新程式碼進行了 CREATE ASSEMBLY。它奏效了。也許它不應該,但它做到了。
所以我開始在下一個數據庫中的下一個程序集中苦苦掙扎。做了同樣的過程(更新框架、簽名、重建、刪除所有引用、刪除程序集、創建程序集)。只有下一次我得到“使用 SAFE 或 EXTERNAL_ACCESS 選項為程序集 XXX 創建或更改程序集失敗,因為 sp_configure 的 ‘clr strict security’ 選項設置為 1。Microsoft 建議您使用證書對程序集進行簽名……”資訊。
我跑了
sp_configure SELECT * FROM sys.trusted_assemblies SELECT * FROM sys.assemblies
在兩個數據庫中。兩者都將“clr strict security”run_value 顯示為 1,兩者都在trusted_assemblies 中不顯示任何條目。
我意識到我的“只是簽署程序集”的理解是不夠的,但我很困惑為什麼該方法在第一個數據庫上有效而在第二個數據庫中失敗了。
我為每個程序集生成了新的 snk 文件,並且我沒有將任何登錄名與它們相關聯。
“只是簽署程序集”是如何在第一次嘗試而不是在第二次嘗試中工作的?
在第一個數據庫中,在 sys.assemblies 的輸出下,我在程序集上看到了新建構的公鑰令牌,我在 permission_set_desc 和新的安裝日期中看到了 SAFE_ACCESS,但我不知道為什麼這樣就足夠了第一個分貝而不是第二個分貝。
謝謝
首先,不需要/不需要重新編譯程序集。它們是否連結到 CLR 2.0 並不重要。SQL Server 2012 和更新版本(至少到 2019 年)僅連結到 CLR 4.0,因此將使用 4.x 系列中安裝在該伺服器上的最高級別的 .NET Framework。這是由於框架 API 中的向後兼容性而起作用的。
其次,這實際上很容易通過就地簽署程序集來解決。簡單地說:
- 使用程序集在數據庫中創建證書
- 簽署大會
[master]
從目前數據庫的證書公鑰創建證書- 從該證書創建登錄
- 授予登錄
UNSAFE ASSEMBLY
權限不需要 SQL Server 外部的任何內容。我在對以下問題的回答中有一個範例(在 DBA.SE 上):
升級到 SQL Server 2017 後,錯誤消息 10314、級別 16、狀態 11 和 SAFE 程序集
在下面的文章中:
SQLCLR 與 SQL Server 2017,第 4 部分:“受信任的程序集”——失望(消息 10314)
第三,我不完全確定為什麼您的行為在第一種情況下有效,但在第二種情況下無效,因為它不應該在第一種情況下有效。如果您沒有
[master]
從程序集中創建非對稱密鑰(或用於對該程序集進行簽名/強命名的 .snk 文件),則成功載入程序集的唯一方法是啟用TRUSTWORTHY
數據庫屬性。您是否有可能在獲得原始錯誤(如果TRUSTWORTHY
啟用則不會發生)和您最終嘗試之間的某個時間這樣做CREATE ASSEMBLY
?