SQL Server 2005 引入 **SQLCLR** 整合 .NET Framework,允許在資料庫內執行 managed code。為確保資料庫引擎穩定與安全,SQLCLR 組件 (Assembly) 必須宣告 **權限集**,決定其可存取的外部資源範圍。本文深度解析三大權限集 (`SAFE`, `EXTERNAL_ACCESS`, `UNSAFE`) 的授予 CAS (Code Access Security) 權限細節、適用場景、部署限制與安全最佳實務。
| 權限集 | 核心能力 | 外部資源存取 | 部署需求 | 風險等級 |
|---|---|---|---|---|
| SAFE (預設) | 純運算、資料存取 (內部)、型別安全驗證 | ❌ 無 (檔案、網路、登錄、其他 SQL 實例) | 資料庫擁有者 (db_owner) 即可部署 | 🟢 低 |
| EXTERNAL_ACCESS | SAFE + 受限外部存取 | ✅ 檔案系統、環境變數、登錄 (唯讀)、DNS、SMTP、其他 SQL 實例 (需 SqlClientPermission) | **資料庫擁有者 + 登入具有 `EXTERNAL ACCESS ASSEMBLY` 伺服器權限** 或資料庫 `TRUSTWORTHY ON` + 簽署憑證/非對稱金鑰 | 🟡 中 |
| UNSAFE | 完全信任,可呼叫 Unmanaged Code、操作記憶體指標、建立執行緒 | ✅ 無限制 (含 P/Invoke、COM、Win32 API) | **sysadmin 固定伺服器角色** 或 `TRUSTWORTHY ON` + 簽署 | 🔴 高 (可能導致 SQL Server 進程崩潰) |
-- 方法一:資料庫 TRUSTWORTHY + 簽署 (推薦生產環境)
ALTER DATABASE MyDB SET TRUSTWORTHY ON; -- 有安全風險,需評估
CREATE ASYMMETRIC KEY SQLCLR_Key FROM EXECUTABLE FILE = 'MyAssembly.dll';
CREATE LOGIN SQLCLR_Login FROM ASYMMETRIC KEY SQLCLR_Key;
GRANT EXTERNAL ACCESS ASSEMBLY TO SQLCLR_Login;
-- 方法二:登入直接授予伺服器權限 (簡單但權限過大)
GRANT EXTERNAL ACCESS ASSEMBLY TO [Domain\User];
[ ] 優先使用 SAFE,滿足 90%+ 業務邏輯
[ ] EXTERNAL_ACCESS 僅用於確定需外部資源的組件
[ ] 部署 EXTERNAL_ACCESS/UNSAFE 採「簽署非對稱金鑰/憑證 + 授予登入權限」模式,**避免 TRUSTWORTHY ON**
[ ] SQLCLR 組件版本管理:來源碼納入版控、編譯輸出簽署、部署腳本化
[ ] 運行期監控:sys.dm_clr_appdomains, sys.dm_clr_loaded_assemblies, sys.dm_clr_tasks
[ ] 記憶體壓力:CLR 記憶體佔用計入 Max Server Memory 外部,需留足緩衝
[ ] 例外處理:所有 SQLCLR 進入點必須 Try/Catch,轉換為 SqlException 拋回 T-SQL