2010-08-16 84 views
3

我正在使用一個系統,該系統必須根據另一個數據庫中創建的對象在一個數據庫中創建對象。對象不重複,所以我不能簡單地複製對象。避免使用SET TRUSTWORTHY ON

我有下面的代碼給出了我試圖做的簡化演示。如果您取消對ALTER DATABASE語句的註釋,那麼它將運行而沒有任何錯誤。儘管如此,這有可能造成安全漏洞,所以我希望儘可能避免它。

我試過使用證書和模擬,但似乎沒有工作。我認爲DDL觸發器在用戶和登錄時忽略了很多安全性。我也嘗試在Test_DB_2中創建一個存儲過程,它調用Test_DB_1中的SP,並讓觸發器調用該存儲過程,但這也沒有幫助。因此,如果你願意接受它,你的挑戰是讓下面的代碼在沒有設置TRUSTWORTHY ON的情況下工作(或者如果有效的話打開數據庫鏈接)。

感謝您的幫助,您可以給!

/************************ 
    SET-UP THE TEST 
************************/ 
USE master 
GO 
CREATE LOGIN Test_Security_Login WITH PASSWORD = '[email protected]!' 
CREATE DATABASE Test_DB_1 
CREATE DATABASE Test_DB_2 
GO 
USE Test_DB_1 
GO 
CREATE PROCEDURE dbo.Create_View 
AS 
BEGIN 
EXEC('CREATE VIEW Test_View AS SELECT 1 AS one') 
END 
GO 
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login 
GRANT EXECUTE ON dbo.Create_View TO Test_Security_User 
GO 
USE Test_DB_2 
GO 
CREATE TRIGGER DDL_TRIGGER ON DATABASE WITH EXECUTE AS 'dbo' FOR DDL_VIEW_EVENTS 
AS 
BEGIN 
EXEC Test_DB_1.dbo.Create_View 
END 
GO 
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login 
EXEC sp_addrolemember 'db_ddladmin', 'Test_Security_User' 

/************************ 
    RUN THE TEST 
************************/ 
USE Test_DB_2 
GO 
--ALTER DATABASE Test_DB_1 SET TRUSTWORTHY ON 
--ALTER DATABASE Test_DB_2 SET TRUSTWORTHY ON 
EXECUTE AS USER = 'Test_Security_User' 
GO 
CREATE VIEW dbo.Test_View_2 AS SELECT 2 AS two 
GO 
REVERT 
GO 

/************************ 
    CLEAN-UP 
************************/ 
USE master 
GO 
DROP DATABASE Test_DB_1 
DROP DATABASE Test_DB_2 
DROP LOGIN Test_Security_Login 
GO 

回答

7

太容易了。使用代碼簽名:

  • 創建自DB1中的簽名證書
  • 標誌使用證書
  • 下降私鑰觸發防止濫用
  • 出口證書到DB2(備份/從文件創建)
  • 從db2中的證書創建證書
  • 授予AUTHENTICATE和證書派生證書的任何其他必要權限
  • 利潤

這是防彈的。有關完整的示例,請參見Call a procedure in another database from an activated procedure

+0

太容易了?不太...你不能簽署DDL觸發器:http://social.msdn.microsoft.com/Forums/en/sqlsecurity/thread/1333eecd-4c66-43d4-ab8f-03511cad4174;) – 2010-08-16 19:30:37

+1

D'oh。 ..好的,那麼很難:不使用DDL觸發器,而是使用事件通知。這會使視圖添加異步(將在原始DDL提交後發生)。有幾種方法:在[msdb]中具有過程的服務器級別EN,具有本地過程的db級別EN簽名以訪問x-db或db級別的EN,並在目標數據庫中使用SSB x-db傳遞和過程執行。選擇你最喜歡的,我會指導你如何去做。 – 2010-08-16 19:42:30

+4

我實際上可以通過使用存根過程調用DDL觸發器的存根過程來使用EXECUTE AS以及使用GRANT AUTHENTICATE實現的證書來使其工作。我曾嘗試過使用存根SP,並嘗試使用證書,但我認爲缺少的部分是AUTHENTICATE權限。一旦我把它降低到最低要求的權限,我會用完整的代碼發佈一個答案,但既然你指出我在正確的方向,我會接受你的答案。謝謝! – 2010-08-16 19:55:04