跨數據庫所有權 - 伺服器主體無法在目前安全上下文下訪問數據庫
我有這個腳本,將一堆數據庫設置為,
same db owner
並設置跨數據庫所有權at database level
select database_name=name, db_owner_name=suser_sname(owner_sid), db_owner_sid=owner_sid, is_db_chaining_on, SQL='USE ' + QUOTENAME(name) + char(10) + 'EXEC sp_changedbowner ''MY_COMPANY\sqldbslaveowner'';' + CHAR(10), CROSS_DB_OWNERSHIP_SQL='USE MASTER' + CHAR(10) + 'ALTER DATABASE ' + QUOTENAME(name) + SPACE(1) + 'SET DB_CHAINING ON;' + CHAR(10) from sys.databases where name in('apcore','junocore','APIA_Repl_Sub','JUNOCore_Repl_Pub','JunoFinance')
它將數據庫所有者設置為一個登錄名,該登錄名沒有與之關聯的權限 -
my_company\sqldbslaveowner
。這是一個AD帳戶。以及以下內容:USE MASTER ALTER DATABASE [JUNOCORE] SET DB_CHAINING ON; USE MASTER ALTER DATABASE [JUNOFinance] SET DB_CHAINING ON; USE MASTER ALTER DATABASE [apcore] SET DB_CHAINING ON; USE MASTER ALTER DATABASE [JUNOCore_Repl_Pub] SET DB_CHAINING ON; USE MASTER ALTER DATABASE [apia_repl_sub] SET DB_CHAINING ON;
所以,完成之後,當我執行下面的命令時,我被排序:
select database_name=name, db_owner_name=suser_sname(owner_sid), db_owner_sid=owner_sid, is_db_chaining_on from sys.databases where name in('apcore','junocore','APIA_Repl_Sub','JUNOCore_Repl_Pub','JunoFinance')
這一切都很好,工作正常,然後昨天,沒有明顯的原因,它分手了,我無法弄清楚缺少的那一點。
我遇到的是以下情況(都在上面顯示的數據庫中):
在其中一個數據庫中,
junofinance
我繼續創建一個儲存過程,該過程從另一個名為JunoCore
. 這一切都應該很好,因為我們在下面cross database ownership
。請注意,該過程具有
execute as owner
並且所有者在兩個數據庫上都是同一個人。我向我的一個應用程序登錄授予執行該過程的權限。
use JUNOFinance go create proc prc2 with execute as owner as begin select * from junocore.[dbo].[agency] end go grant execute on prc2 to [juno] go
現在,當我執行此過程時,出現以下錯誤:
use JUNOFinance go execute as login='juno' exec prc2
伺服器主體“My_Company\sqldbslaveowner”無法在目前安全上下文下訪問數據庫“JUNOCORE”。
這工作正常。
我將不得不檢查 創建證書,因為它以前都在工作!
數據庫是可用性組的一部分
只有 msdb 設置為可信任
正如我所說的一切正常,我最近唯一做的就是將 sql server 2016 升級到 SP2,但我對這台伺服器沒有任何問題。
還有什麼可以建議我解決這種情況?
伺服器主體“My_Company\sqldbslaveowner”無法在目前安全上下文下訪問數據庫“JUNOCORE”。
在這種情況下,您不需要 EXECUTE AS OWNER ,因為在模擬數據庫主體時無法跨數據庫,它會中斷。模擬和所有權鍊是兩種獨立的授權機制。
人們忘記的正常情況是最終使用者必須具有對目標數據庫的*數據庫訪問權限。*跨數據庫所有權鏈不授予使用者訪問數據庫的權限,它們僅禁止對該數據庫中的對象進行權限檢查。
這是一個簡單的複制:
/* revert use master drop database a drop database b drop login appuser */ go create database a create database b ALTER DATABASE a SET DB_CHAINING ON; ALTER DATABASE b SET DB_CHAINING ON; go use b go create procedure foo as begin select 1 a; end go use a go create procedure foo as begin exec b.dbo.foo; end go create login appuser with password='P@Jhs9d!$12' create user appuser for login appuser grant exec on foo to appuser go execute as login='appuser' exec foo; --fails --Msg 916, Level 14, State 1, Procedure foo, Line 4 [Batch Start Line 37] --The server principal "appuser" is not able to access the database "b" under the current security context. go revert go use b create user appuser for login appuser deny select,insert,update,execute to appuser --not strictly necessary go use a execute as login='appuser' exec foo; revert --works go --`execute as owner` is incompatible with cross database ownership chains create or alter procedure foo with execute as owner as begin exec b.dbo.foo; end go use a execute as login='appuser' exec foo; revert --fails --Msg 916, Level 14, State 1, Procedure foo, Line 5 [Batch Start Line 69] --The server principal "NORTHAMERICA\dbrowne" is not able to access the database "b" under the current security context.