Sql-Server

跨數據庫所有權 - 伺服器主體無法在目前安全上下文下訪問數據庫

  • October 9, 2018

我有這個腳本,將一堆數據庫設置為,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.

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