Ich bin froh, dass Sie dies gelöst haben, aber die Verkettung von Eigentumsrechten ist nicht die empfohlene Lösung. Da Sie anscheinend ernsthaft besorgt über die Sicherheit und die ordnungsgemäße Granularität der betreffenden Rechte sind, füge ich diese Antwort hinzu, obwohl sie zu spät ist, als Hinweis darauf, was passiert und wie diese Probleme gelöst werden können.
AUSFÜHREN ALS Identitätswechselbereich
Die EXECUTE AS-Klauseln gibt es in zwei Varianten: EXECUTE AS LOGIN und EXECUTE AS USER. Das EXECUTE AS LOGIN wird vom Server authentifiziert und ist ein Identitätswechselkontext, dem die gesamte SQL-Instanz vertraut (mit Serverbereich):
Wenn Sie sich als Principal ausgeben, indem Sie die EXECUTE AS LOGIN-Anweisung verwenden, oder innerhalb eines Moduls mit Serverbereich, indem Sie die EXECUTE AS-Klausel verwenden, ist der Umfang des Identitätswechsels serverweit. Dies bedeutet, dass nach dem Kontextwechsel auf jede Ressource innerhalb des Servers zugegriffen werden kann, für die die Identitätswechselberechtigung Berechtigungen hat.
EXECUTE AS USER wird von der Datenbank authentifiziert und ist ein Identitätswechselkontext, dem nur diese Datenbank vertraut (datenbankbezogen):
Wenn Sie sich jedoch als Principal ausgeben, indem Sie die EXECUTE AS USER-Anweisung verwenden, oder innerhalb eines Moduls mit Datenbankbereich, indem Sie die EXECUTE AS-Klausel verwenden, ist der Umfang des Identitätswechsels standardmäßig auf die Datenbank beschränkt. Dies bedeutet, dass Verweise auf Objekte außerhalb des Bereichs der Datenbank einen Fehler zurückgeben.
Eine gespeicherte Prozedur mit einer EXECUTE AS-Klausel erstellt einen Identitätswechselkontext mit Datenbankbereich und kann daher keine Objekte außerhalb der Datenbank referenzieren. In diesem Fall können Sie nicht referenzieren, msdb.dbo.sp_start_job
da sich in befindet msdb
. Es stehen viele andere Beispiele zur Verfügung, z. B. der Versuch, auf eine DMV mit Serverbereich zuzugreifen, ein Verbindungsserver zu verwenden oder eine Service Broker-Nachricht in eine andere Datenbank zu übermitteln.
Um einem Identitätswechsel mit Datenbankbereich den Zugriff auf eine Ressource zu ermöglichen, die normalerweise nicht zulässig ist, muss dem Authentifikator des Identitätswechselkontexts vertraut werden. Bei einem Identitätswechsel mit Datenbankbereich ist der Authentifikator die Datenbank dbo. Dies kann auf zwei Arten erreicht werden:
- Durch Aktivieren der TRUSTWORTHY-Eigenschaft in der Datenbank, die den Identitätswechselkontext authentifiziert hat (dh in der Datenbank, in der die EXECUTE AS-Klausel ausgegeben wurde).
- Durch die Verwendung von Codesignaturen.
Diese Details werden in MSDN: Erweitern des Datenbankidentitätswechsels mithilfe von EXECUTE AS beschrieben .
Wenn Sie das Problem über eine datenbankübergreifende Verkettung behoben haben, haben Sie die datenbankübergreifende Verkettung auf der gesamten Serverebene aktiviert, was als Sicherheitsrisiko angesehen wird. Der am besten kontrollierte und feinkörnige Weg, um das gewünschte Ergebnis zu erzielen, ist die Verwendung der Codesignatur:
- Erstellen Sie in der Anwendungsdatenbank ein selbstsigniertes Zertifikat
- Unterschreiben Sie das
dbo.StartAgentJob
mit diesem Zertifikat
- Löschen Sie den privaten Schlüssel des Zertifikats
- Exportieren Sie das Zertifikat auf die Festplatte
- Importieren Sie das Zertifikat in
msdb
- Erstellen Sie einen abgeleiteten Benutzer aus dem importierten Zertifikat in
msdb
- Erteilen Sie dem abgeleiteten Benutzer in die Berechtigung AUTHENTICATE
msdb
Diese Schritte stellen sicher, dass dem EXECUTE AS-Kontext der dbo.StartAgentJob
Prozedur jetzt vertraut wird msdb
, da der Kontext von einem Principal signiert ist, der über die Berechtigung AUTHENTICATE verfügt msdb
. Dies löst die Hälfte des Puzzles. Die andere Hälfte besteht darin, die EXECUTE-Berechtigung msdb.dbo.sp_start_job
für den jetzt vertrauenswürdigen Identitätswechselkontext zu erteilen . Dies kann auf verschiedene Arten geschehen:
- Ordnen Sie den imitierten Benutzer dem
agentProxy
Benutzer zu msdb
und erteilen Sie ihm die Ausführungsberechtigung fürmsdb.dbo.sp_start_job
- Erteilen Sie dem vom
msdb
Authentifizierungszertifikat abgeleiteten Benutzer die Ausführungsberechtigung
- Fügen Sie der Prozedur eine neue Signatur hinzu, leiten Sie einen Benutzer dafür ab
msdb
und erteilen Sie diesem abgeleiteten Benutzer die Ausführungsberechtigung
Option 1. ist einfach, hat aber einen großen Nachteil: Der agentProxy
Benutzer kann das nun nach msdb.dbo.sp_start_job
eigenem Ermessen ausführen , erhält wirklich Zugriff auf msdb
und verfügt über die Ausführungsberechtigung.
Option 3 ist durchaus richtig, aber ich halte es für unnötig übertrieben.
Daher wird Option 2 bevorzugt: Erteilen Sie msdb.dbo.sp_start_job
dem in Zertifikaten abgeleiteten Benutzer, der in erstellt wurde , die EXECUTE-Berechtigung msdb
.
Hier ist das entsprechende SQL:
use [<appdb>];
go
create certificate agentProxy
ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
with subject = 'agentProxy'
, start_date='01/01/2009';
go
ADD SIGNATURE TO OBJECT::[StartAgentJob]
BY CERTIFICATE [agentProxy]
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y';
go
alter certificate [agentProxy]
remove private key;
go
backup certificate [agentProxy]
to file='c:\temp\agentProxy.cer';
go
use msdb
go
create certificate [agentProxy]
from file='c:\temp\agentProxy.cer';
go
create user [agentProxyAuthenticator]
from certificate [agentProxy];
go
grant authenticate to [agentProxyAuthenticator];
grant execute on msdb.dbo.sp_start_job to [agentProxyAuthenticator];
go
use [<appdb>];
go
exec dbo.StartAgentJob;
go
Mein Blog enthält einige Artikel zu diesem Thema, die im Zusammenhang mit von Service Broker aktivierten Prozeduren geschrieben wurden (da für sie eine EXECUTE AS-Klausel erforderlich ist):
Übrigens, wenn Sie versuchen, mein Skript zu testen und auf der östlichen Hemisphäre oder im Sommer in Großbritannien leben, lesen Sie auf jeden Fall den letzten Artikel, den ich vor dem Testen verlinkt habe.