跨數據庫觸發器:伺服器主體無法在目前安全上下文下訪問數據庫
我有兩個數據庫
Source
並Target
託管在同一個 SQL Server 2008 R2 實例中。我有一個登錄名,它映射到兩個數據庫中的使用者。每個映射使用者在其各自的數據庫中都有一個角色,該角色授予對該數據庫中所有對象的訪問權限。我有一個跨數據庫觸發器,它將更新從表傳播
Source
到Target
.當我使用 Login 連接到SQL Server Managment Studio中的伺服器並在 上執行
update
查詢時Source
,跨數據庫更新成功。但是,當在應用程序中使用相同的登錄名啟動等效更新時,觸發器會失敗並出現錯誤:
伺服器主體“名稱”無法在目前安全上下文下訪問數據庫“目標”。
通過使用 SQL Server Profiler 執行跟踪,我可以驗證
update
在兩種情況下都在相同的 LoginName 下執行。問題:
- 允許跨數據庫觸發器工作的 SSMS 有什麼特別之處?
- “目前安全上下文”是什麼意思?
- 我需要修改什麼以允許更新+觸發器在應用程序的上下文中工作?
我已經閱讀了有關對象所有權連結的資訊,但我還沒有完全調查過。但由於它在 SSMS 中有效,我很想相信所有權鏈斷裂不是問題所在。但我可能錯了!對於任何診斷建議,我將不勝感激。
更新:我正在嘗試實施srutzky的建議。這就是我到目前為止所執行的。
use [SourceDB]; create certificate [Access_TargetDB] encryption by password = 'password123' with subject = 'Cross-DB Access to TargetDB', expiry_date = '2099-12-31'; add signature to [MyTrigger] by certificate [Access_TargetDB] with password = 'password123'; backup certificate [Access_TargetDB] to file = 'C:\Access_TargetDB.cert'; use [TargetDB]; create certificate [SourceDB] from file = 'C:\Access_TargetDB.cert'; create user [SourceDBUser] for certificate [SourceDB]; exec sp_addrolemember 'StandardUserRole', 'SourceDBUser';
SourceDB
嘗試使用應用程序角色上下文更新表時,我仍然遇到相同的錯誤。我正在嘗試實施srutzky的第二個建議。除了上述之外,我還執行了以下內容。但是該建議假設了一個我沒有的目標儲存過程,所以這實際上可能不是一個有效的測試。
use master; create certificate [SourceDB] from file = 'C:\SourceDB.cert'; create login [SourceDBLogin] from certificate [SourceDB]; grant authenticate server to [SourceDBLogin];
應用程序角色上下文中可用的權限仍然沒有變化。
這應該很容易通過模組簽名來完成。在 DBA.SE 上查看我的其他答案:
基本概念如下:
- 在源數據庫(即存在觸發器的位置)中創建證書。
- 使用 簽署觸發器
ADD SIGNATURE
。- 在目標數據庫中創建相同的證書。
- 從該證書在目標數據庫中創建一個使用者。
- 授予對目標數據庫中的表的基於證書的使用者
INSERT, UPDATE
權限。
我發現從應用程序內部啟動的更新+觸發器的問題是因為應用程序正在使用應用程序角色來取代登錄的安全上下文。
可以在 Brian Kelley 的這篇博文中找到更多資訊:SQL Server 安全性:應用程序角色的優點和缺點。特別是:
當應用程序角色生效時,它將覆蓋連接的任何數據庫和登錄憑據。這意味著如果我嘗試使用 Northwind.dbo.Customers 等三部分命名約定訪問另一個數據庫,我將不會根據我的原始登錄名映射到數據庫。我唯一可以使用的使用者是訪客。
所以回答具體問題:
- SSMS 並不特殊;它是阻止跨數據庫訪問的應用程序。
- 目前的安全上下文是授予/拒絕權限的登錄令牌和使用者令牌的列表。例如,以下查詢在 SSMS 中執行時返回兩行
SELECT name, type, usage FROM sys.login_token; name type usage ------------ -------------- --------------- mylogin SQL LOGIN GRANT OR DENY public SERVER ROLE GRANT OR DENY
當在應用程序角色的上下文中執行相同的查詢時,只
public
保留登錄令牌,並且該令牌的用法變為“僅拒絕”。有關 TechNet 的更多資訊:了解執行上下文 3. 我還在尋找解決方案!應用程序開發人員不會放棄最近添加的應用程序角色。
public
將必要的權限授予數據庫中的角色是非常不明智的Target
。