我使用的系统必须在一个数据库中基于在另一个数据库中创建的对象创建对象。这些对象不是重复的,所以我不能简单地复制这些对象。
下面的代码对我要做的事情进行了简单的演示。如果您取消对
ALTER DATABASE
语句,然后它将运行而不出现任何错误。不过,这有可能造成安全漏洞,所以如果可能的话,我想避免出现这种情况。
我试过使用证书和冒充,但似乎没什么效果。我认为当涉及到用户和登录时,DDL触发器忽略了很多安全性。我还尝试在test_db_2中创建一个存储过程,它调用test_db_1中的sp,并让触发器调用该存储过程,但这也没有帮助。
因此,如果您愿意接受它,您的挑战是让下面的代码在不设置值得信赖的情况下工作(或者如果有任何影响,则打开DB链接)。
谢谢你的帮助!
/************************
SET-UP THE TEST
************************/
USE master
GO
CREATE LOGIN Test_Security_Login WITH PASSWORD = 'p@ssw0rd1!'
CREATE DATABASE Test_DB_1
CREATE DATABASE Test_DB_2
GO
USE Test_DB_1
GO
CREATE PROCEDURE dbo.Create_View
AS
BEGIN
EXEC('CREATE VIEW Test_View AS SELECT 1 AS one')
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
GRANT EXECUTE ON dbo.Create_View TO Test_Security_User
GO
USE Test_DB_2
GO
CREATE TRIGGER DDL_TRIGGER ON DATABASE WITH EXECUTE AS 'dbo' FOR DDL_VIEW_EVENTS
AS
BEGIN
EXEC Test_DB_1.dbo.Create_View
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
EXEC sp_addrolemember 'db_ddladmin', 'Test_Security_User'
/************************
RUN THE TEST
************************/
USE Test_DB_2
GO
--ALTER DATABASE Test_DB_1 SET TRUSTWORTHY ON
--ALTER DATABASE Test_DB_2 SET TRUSTWORTHY ON
EXECUTE AS USER = 'Test_Security_User'
GO
CREATE VIEW dbo.Test_View_2 AS SELECT 2 AS two
GO
REVERT
GO
/************************
CLEAN-UP
************************/
USE master
GO
DROP DATABASE Test_DB_1
DROP DATABASE Test_DB_2
DROP LOGIN Test_Security_Login
GO