Sql-Server

跨數據庫視圖 - 在目前安全上下文下無法訪問數據庫

  • January 3, 2018

我們有兩個數據庫,AdbBdb. 在Bdb中,我們創建一個引用另一個視圖的視圖,如下所示AdbCREATE VIEW Bdb.dbo.Bview AS SELECT * FROM Adb.dbo.Aview

我們有一個 SQL Authenticated Blogin,映射到Buser,都在AdbBdb上,至少db_datareader在兩者上都有角色。

以下不起作用:

USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Bdb.dbo.Bview;
SELECT * FROM Adb.dbo.Aview;

兩種選擇都會引發以下錯誤:

Msg 916, Level 14, State 1, Line 4
The server principal "Buser" is not able to access the database "Adb" under the current security context.

但是,這有效:

USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Adb.dbo.Aview;
SELECT * FROM Bdb.dbo.Bview;

我注意到,當我第一次USE Bdb切換到時Buser,我看不到任何其他數據庫:

USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- only master, tempdb and Bdb is shown

但是,當我USE Adb第一次看到它們時,我看到了所有這些,即使是那些沒有Buser並且不能被它訪問的:

USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- all DBs on the server are shown

什麼可能導致此問題?我應該檢查什麼?

首先要做的事情:不要啟用可信!絕對沒有理由打開這麼大的安全漏洞。(注意:msdbTRUSTWORTHY啟用,這很好,因為它是 Microsoft 提供的數據庫;使用者創建的數據庫永遠不需要 TRUSTWORTHY啟用)

現在,如果這在模擬使用者而不是登錄時有效,那是因為您的[Adb]數據庫已啟用為TRUSTWORTHY ON,這將刪除使用數據庫級模擬時存在的預設隔離區。您可以通過執行以下命令來看到這一點:

SELECT db.is_trustworthy_on, *
FROM   sys.databases db
WHERE  db.[name] IN (N'Adb', N'Bdb');

假設Adb是啟用TRUSTWORTHYBdb沒有啟用的情況,那麼還是請不要啟用TRUSTWORTHYfor Bdb。最好禁用 TRUSTWORTHYforAdb並使用模組簽名來完成此操作:

ALTER DATABASE [Adb] SET TRUSTWORTHY OFF;

有關通過模組簽名進行此跨數據庫訪問的範例,請參閱我的以下答案(在 DBA.SE 上):

基於另一個數據庫中的表的訪問視圖,而沒有該其他數據庫中的帳戶

有關為什麼應該使用模組簽名而不是 TRUSTWORTHY(甚至是跨數據庫所有權連結)的更多資訊,請參閱我的以下文章:

請,請,請停止使用模擬、可信和跨數據庫所有權連結

有關模組簽名的更多資訊,請參閱:

https://ModuleSigning.info/


正如@Nic 在對該問題的評論中提到的那樣,最好在測試時使用EXECUTE AS LOGIN而不是使用。EXECUTE AS USER登錄位於伺服器級別,並且可以訪問已為該登錄創建使用者的數據庫。這就像以該帳戶登錄 SQL Server 一樣。

差異的原因在 Microsoft 文件頁面中說明了通過使用 EXECUTE AS 擴展數據庫模擬

了解模擬範圍

但是,當使用 EXECUTE AS USER 語句或在數據庫範圍的模組中使用 EXECUTE AS 子句模擬主體時,預設情況下模擬的範圍僅限於數據庫。這意味著對數據庫範圍之外的對象的引用將返回錯誤。

此外,“Extending Database Impersonation by Using EXECUTE AS”MSDN 頁面(上面連結)上有很多很好的資訊,解釋了身份驗證器和這些規則背後的推理。

鑑於這兩個數據庫是供應商提供的(在我送出此答案後添加了資訊),那麼最好只切換到數據庫EXECUTE AS LOGIN而不數據庫進行任何更改(用於模組簽名)。

引用自:https://dba.stackexchange.com/questions/194366