在一个数据库上运行的触发器以execute as owner运行,即使用户是两个数据库的dbo,也无法在运行时插入另一个数据库。
错误:服务器主体“AUser”无法访问当前安全上下文下的数据库“DatabaseB”。
示例触发器:
CREATE TRIGGER "MyTrigger"
ON "DatabaseA".dbo.MyTable
WITH EXECUTE AS OWNER
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO DatabaseB.dbo."MyOtherTable" (ColumnA) VALUES ('test');
END
GO
“AUser”是DatabaseA和DatabaseB的DBO,更新“DatabaseA”.dbo.MyTable中的记录现在将导致服务器主体错误
编辑:在DatabaseA上启用TRUSTWORTHY修复此问题,但我宁愿不这样做
答案 0 :(得分:3)
这是因为您已经使用了" WITH EXECUTE AS OWNER"子句。
当您的DML触发器/存储过程使用" WITH EXECUTE AS"时,模拟的主体是用户,而不是登录,您可以在此处清楚地看到它:
EXECUTE AS Clause (Transact-SQL)
' user_name'
指定模块内执行的语句 user_name中指定的用户的上下文。任何权限 模块中的对象将根据user_name进行验证。用户名 无法为具有服务器作用域或登录的DDL触发器指定 触发。请改用login_name。
因此,使用execute as user子句,您已在数据库中沙箱化了执行。
当您不使用此子句时,将通过登录执行过程/触发器,因此如果登录能够访问另一个数据库,则它将起作用。但是,通过以用户身份执行,您不再使用登录,因此即使所有者 sa ,您仍然会遇到相同的错误:< / p>
服务器主体&#34; sa&#34; 无法访问数据库 &#34; DatabaseB&#34;在当前的安全背景下。
解决此问题的不安全方法是让databaseA
TRUSTWORTHY
+其所有者获得AUTHENTICATE SERVER
权限。
如果db_owners
databaseA
sysadmins
不是sysadmin
,则可以使用此功能,否则他们可以将权限提升为certificates
。
其他方式更复杂,但 secur e:使用c0 - c11 - c12 - c13
\
c21 - c22
。