3
我正在使用一个系统,该系统必须根据另一个数据库中创建的对象在一个数据库中创建对象。对象不重复,所以我不能简单地复制对象。避免使用SET TRUSTWORTHY ON
我有下面的代码给出了我试图做的简化演示。如果您取消对ALTER DATABASE
语句的注释,那么它将运行而没有任何错误。尽管如此,这有可能造成安全漏洞,所以我希望尽可能避免它。
我试过使用证书和模拟,但似乎没有工作。我认为DDL触发器在用户和登录时忽略了很多安全性。我也尝试在Test_DB_2中创建一个存储过程,它调用Test_DB_1中的SP,并让触发器调用该存储过程,但这也没有帮助。因此,如果你愿意接受它,你的挑战是让下面的代码在没有设置TRUSTWORTHY ON的情况下工作(或者如果有效的话打开数据库链接)。
感谢您的帮助,您可以给!
/************************
SET-UP THE TEST
************************/
USE master
GO
CREATE LOGIN Test_Security_Login WITH PASSWORD = '[email protected]!'
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
太容易了?不太...你不能签署DDL触发器:http://social.msdn.microsoft.com/Forums/en/sqlsecurity/thread/1333eecd-4c66-43d4-ab8f-03511cad4174;) – 2010-08-16 19:30:37
D'oh。 ..好的,那么很难:不使用DDL触发器,而是使用事件通知。这会使视图添加异步(将在原始DDL提交后发生)。有几种方法:在[msdb]中具有过程的服务器级别EN,具有本地过程的db级别EN签名以访问x-db或db级别的EN,并在目标数据库中使用SSB x-db传递和过程执行。选择你最喜欢的,我会指导你如何去做。 – 2010-08-16 19:42:30
我实际上可以通过使用存根过程调用DDL触发器的存根过程来使用EXECUTE AS以及使用GRANT AUTHENTICATE实现的证书来使其工作。我曾尝试过使用存根SP,并尝试使用证书,但我认为缺少的部分是AUTHENTICATE权限。一旦我把它降低到最低要求的权限,我会用完整的代码发布一个答案,但既然你指出我在正确的方向,我会接受你的答案。谢谢! – 2010-08-16 19:55:04