Je travaille avec un système qui devait créer des objets dans une base de données en fonction des objets créés dans une autre base de données. Les objets ne sont pas des doublons, donc je ne peux pas simplement répliquer les objets.Éviter l'utilisation de SET TRUSTWORTHY ON
J'ai le code ci-dessous qui donne une démonstration simplifiée de ce que j'essaie de faire. Si vous décommentez les instructions ALTER DATABASE
, il s'exécutera sans aucune erreur. Cela a le potentiel de créer un trou de sécurité, donc je voudrais l'éviter si possible.
J'ai essayé d'utiliser des certificats et des usurpations d'identité, mais rien ne semble fonctionner. Je pense que le déclencheur DDL ignore une grande partie de la sécurité en ce qui concerne les utilisateurs et les connexions. J'ai également essayé de créer une procédure stockée dans Test_DB_2 qui appelle le SP dans Test_DB_1 et ayant l'appel de déclencheur cette procédure stockée à la place, mais cela n'a pas aidé non plus. Donc, votre défi, si vous voulez l'accepter, est de faire fonctionner le code ci-dessous sans activer TRUSTWORTHY ON (ou activer le chaînage db si cela a un effet).
Merci pour toute aide que vous pouvez donner!
/************************
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
Trop facile? Pas tout à fait ... vous ne pouvez pas signer un déclencheur DDL: http://social.msdn.microsoft.com/Forums/en/sqlsecurity/thread/1333eecd-4c66-43d4-ab8f-03511cad4174;) –
D'oh. .. OK, alors à la dure: au lieu d'utiliser les déclencheurs DDL, utilisez les notifications d'événements. Cela rendra l'ajout de la vue asynchrone (se produira après que le DDL original a été engagé). Il existe plusieurs manières: niveau serveur EN avec procédure dans [msdb], niveau db EN avec procédure locale signée pour accéder à x-db ou niveau db EN avec livraison SSB x-db et exécution de procédure dans la cible db. Choisissez votre favori et je vais vous guider comment le faire. –
J'ai effectivement réussi à le faire fonctionner en utilisant une procédure stub stockée appelée par le déclencheur DDL avec le SP stub utilisant EXECUTE AS et avec des certificats implémentés en utilisant GRANT AUTHENTICATE. J'avais essayé d'utiliser un SP stub avant et j'avais essayé d'utiliser des certificats, mais la pièce manquante je pense était la permission AUTHENTICATE. Une fois que je l'aurai réduit au minimum requis, je posterai une réponse avec le code complet, mais puisque vous m'avez indiqué la bonne direction, je vais accepter votre réponse. Merci! –