Ausführen einer gespeicherten Prozedur, die auf eine andere SQL-Instanz zugreift

8

Ich entschuldige mich, wenn diese Frage eine andere bereits gestellte wiederholt. Ich habe stundenlang gesucht und keine gefunden, die zu meiner Situation passt.

Gewünschtes Ergebnis

Ein Benutzer, der die SQL-Authentifizierung verwendet, hat Ausführungsberechtigungen für Datenbank1 auf Server1 (Standardinstanz), und das ist es. Der Benutzer führt eine gespeicherte Prozedur aus, die als Teil seines Prozesses auf Datenbank 2 auf Server1 \ Instanz2 zugreift. Ich möchte, dass es sicher und einfach ist (beide sind wichtig).

Mehr Info

Meine Windows-Anmeldeinformationen haben Zugriff auf beide Instanzen (die sich auf demselben Server befinden). Daher kann ich die gespeicherte Prozedur unter meinem Login problemlos ausführen. Ich möchte dem Benutzer jedoch nicht meine Zugriffsebene gewähren. Ich muss auch eine SQL-Anmeldung verwenden, da sich der Benutzer nicht in der Domäne befindet.

Was ich möchte, wäre, der gespeicherten Prozedur meine Zugriffsebene nur für diese Prozedur zu geben. Da ich ein Systemadministrator bin, würde dies dem Benutzer alles geben, was er für dieses Verfahren benötigt. Wenn ich das zum Laufen bringen würde, würde ich wahrscheinlich nur zu diesem Zweck ein Konto erstellen, anstatt mein Konto zu verwenden, aber so oder so wäre es sicher, da ich kontrolliere, was der gespeicherte Prozess tut.

Ich habe versucht, die Anweisung "WITH EXECUTE AS" in meinen gespeicherten Prozess einzufügen, konnte sie jedoch nicht dazu bringen, meine Windows-Anmeldeinformationen zu übernehmen. Wenn ich es einfüge, wird beim Kompilieren des gespeicherten Prozesses der folgende Fehler angezeigt:

Kann nicht als Benutzer 'domain \ jdoe' ausgeführt werden, da dieser nicht vorhanden ist oder Sie keine Berechtigung haben.

Der Benutzer ist auf beiden Servern Sysadmin, wie ich bereits sagte, daher bin ich mir nicht sicher, was er noch benötigt.

Ich habe Folgendes untersucht:

  • VERTRAUEN - Ich würde meine Datenbank lieber nicht offenlegen und das sieht beängstigend aus
  • Verbindungsserver - Ich möchte keine zusätzlichen Berechtigungen erteilen. Ich vertraue nicht darauf, dass die andere Datenbank Zugriff auf meine Datenbank hat, und ich vertraue nicht darauf, dass meine Datenbank Zugriff auf alle anderen Datenbanken hat.
  • Zertifikate - Dies scheint kompliziert und schwierig. Ich bin mir nicht sicher, ob es die Mühe wert ist, es sei denn, ich könnte einen sehr einfachen Weg finden, dies zu tun und zu warten.
  • Eigentumsverkettung - Wieder beängstigend. Es sieht so aus, als würde dies mehr Sicherheitsprobleme verursachen, wenn mein Ziel darin besteht, Sicherheitsprobleme zu vermeiden.
  • Gespiegelter Benutzer - Ich habe sogar denselben Benutzer (offensichtlich mit einer anderen SID) auf der anderen Serverinstanz erstellt und ihm dasselbe Kennwort gegeben. No Go.

Ich habe das Gefühl, dass mir etwas Offensichtliches fehlt, aber ich bin mir nicht sicher, was es ist. Da ich den ganzen Tag meinen Kopf gegen die Wand geschlagen habe, bin ich wahrscheinlich zu nah dran, um es zu sehen. Ich würde es sehr schätzen, wenn jemand hier mir helfen oder mich in die richtige Richtung weisen könnte. Ich werde sagen, dass ich viele MSDN-Artikel gelesen habe (Junge, hasse ich sie - sie scheinen mir nie zu sagen, was ich wissen möchte). Was ich wirklich gerne hätte, ist ein einfaches, leicht zu befolgendes Tutorial, das mich durch die Vorgehensweise führt. Ansonsten wäre sogar ein allgemeiner Hinweis auf die Richtung, in die ich gehen muss, hilfreich.

IAmTimCorey
quelle

Antworten:

3

Versuchen Sie stattdessen EXECUTE AS LOGIN = 'DOMAIN \ username' und prüfen Sie, ob dies funktioniert.

mrdenny
quelle
Ich habe das versucht, aber dieser Befehl ist offensichtlich nicht für das Speichern in einer gespeicherten Prozedur vorgesehen.
IAmTimCorey
Es sollte in einer gespeicherten Prozedur einwandfrei funktionieren. Hat Ihr Konto ein eigenes Login erstellt oder erhalten Sie Ihre Rechte über eine Gruppenmitgliedschaft?
Mrdenny
Mein Konto verfügt über ein eigenes Login mit Sysadmin-Rechten. Es verfügt auch über Domänenadministratorrechte durch Gruppenmitgliedschaft, sodass ich alles habe, was ich brauche, und dies auch, wenn ich mit meinen Windows-Anmeldeinformationen angemeldet bin. Ich habe jedoch zwei Dinge herausgefunden. Wenn ich Ihren obigen Code in der WITH-Anweisung eines gespeicherten Prozesses verwende, erhalte ich zunächst einen Syntaxfehler. Wenn ich es in eine Anweisung einfüge, funktioniert es innerhalb einer Instanz, jedoch nicht instanzübergreifend.
IAmTimCorey
3

Schauen Sie sich die Verwendung von EXECUTE AS+ Trustworthy an. Sie können es dort einrichten, wo es innerhalb der gespeicherten Prozedur aufgerufen werden kann, solange Benutzer b Zugriff erhalten hat und die beiden Datenbanken sich gegenseitig vertrauen.

Dieser Blog sollte antworten oder alles bieten, was Sie brauchen. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

die Verwendung der Datenbankeigenschaft TRUSTWORTHY, um den Zugriff auf Ressourcen außerhalb des Bereichs der Quellendatenbank zu steuern

http://msdn.microsoft.com/en-us/library/ms188304%28v=sql.90%29.aspx

SoftwareCarpenter
quelle
Das Problem, das ich dabei sehe, ist, dass Trustworthy eine Vertrauensbeziehung zwischen den beiden Datenbanken herstellt. Dies kann von Systemadministratoren auf beiden Seiten ausgenutzt werden. Ich will das nicht Ich versuche, die Berechtigungen einer Person einzuschränken. Wenn ich einer anderen Person noch mehr Berechtigungen erteile, ist das keine gute Sache. Trotzdem danke.
IAmTimCorey
Beachten Sie hier, dass einzelne Eigentümer keine physischen Personen sein müssen, sondern dass es sich um eine generische Anmeldung für jede Datenbank handeln kann. Sie müssen nicht die gesamte Datenbank über gewähren. Wenn Sie den Systemadministratoren in der anderen Datenbank nicht vertrauen, bestehen Sie auf der Signatur des Zertifikats.
SoftwareCarpenter
Sie haben in Ihrer Antwort unten erwähnt, dass Sie auf den Link sommarskog.se/grantperm.html gestoßen sind. Das ist der gleiche Blog, den ich in der von mir vorgeschlagenen Antwort gepostet habe. "Dieser Blog sollte antworten oder alles bieten, was Sie brauchen. Sommommkk.se/grantperm.html#EXECAScrossdb " Vielleicht haben Sie nur für andere referenziert. Ich bin damit einverstanden, dass es ein guter Blog ist und lese. Viel Glück!
SoftwareCarpenter
Ja, tut mir leid, ich habe vergessen zu sagen, dass der Link von Ihnen stammt. Es war eine gute Ressource. Danke für Ihre Hilfe.
IAmTimCorey
2

Nachdem ich das Thema ausführlich gelesen und einige Experimente durchgeführt habe, glaube ich, dass ich zu einem Schluss gekommen bin. Die EXECUTE AS-Anweisung ist nicht für die instanzübergreifende Arbeit ohne größere Auswirkungen auf die Sicherheit ausgelegt. Was ich mir erhofft hatte, war eine Möglichkeit, meinem Verfahren mitzuteilen, unter welcher Windows-Identität ich ausgeführt werden wollte, da eine Windows-Identität auf mehrere Ressourcen auf mehreren Servern zugreifen kann. Selbst nachdem ich mit verschiedenen Einstellungen herumgespielt hatte, stellte sich heraus, dass ich andere Sicherheitsmaßnahmen schwächen musste, damit eine gespeicherte Prozedur sich als ich ausgeben konnte.

Es scheint nicht viele Informationen über instanz- oder serverübergreifende Prozeduren zu geben. Ich würde mir vorstellen, dass der Grund dafür in den Auswirkungen auf Sicherheit und Leistung liegt. Ich glaube jedoch, dass es Fälle gibt, in denen dies wichtig ist, und es scheint, dass die Lösungen dafür kompliziert und sehr szenariospezifisch sind. Ich bin auf einen guten Artikel gestoßen, der mir zumindest geholfen hat, einige meiner Optionen zu verstehen. Es war nicht auf den instanzübergreifenden Zugriff ausgerichtet, aber es gab mir die Hinweise, die ich suchte. Ich würde Sie ermutigen, es auszuprobieren:

http://www.sommarskog.se/grantperm.html

Ich wäre immer noch an anderen Lösungen für dieses Problem interessiert, aber meine derzeitige Lösung ist zweifach. Wenn ich unbedingt über eine gespeicherte Prozedur auf zwei Datenbanken zugreifen muss, muss ich zunächst ein Windows-Login verwenden. Ich vermeide dies jedoch, wann immer dies möglich ist, da dies zu Leistungsproblemen führt (Sperren mehrerer Server, Netzwerkkomplikationen, Unfähigkeit, die Abfrage zu optimieren usw.). Zweitens bringe ich die Daten aus jeder Datenbank durch separate, datenbankspezifische Aufrufe. Das heißt, ich bringe die Daten vor dem Zusammenführen zum Client zurück. Es ist nicht so performant oder sauber, wie ich es gerne hätte, aber es scheint die sicherste Lösung zu sein.

IAmTimCorey
quelle
1

Wenn Sie auf Datenbankobjekte zwischen zwei SQL Server-Instanzen zugreifen müssen, würde ich eine der folgenden Optionen empfehlen:

  1. Erstellen und verwenden Sie einen Verbindungsserver zwischen den beiden Instanzen mit der entsprechenden Berechtigung für den Zugriff auf das Objekt auf der Zielinstanz (Remote-Instanz).
  2. Verwenden Sie SSIS und rufen Sie das Paket von der Quellinstanz von SQL Server aus auf. Abhängig davon, welche Version von SQL Server verwendet wird, können Sie entweder einen SQL Agent-Job haben (nicht für die Ausführung geplant, sondern von der gespeicherten Prozedur aufgerufen) oder die SSISDB verwenden, um das SSIS-Paket aufzurufen, das auf das Datenbankobjekt auf der Remote-Instanz zugreift.
  3. Verschieben Sie die Logik in die mittlere Ebene (oder auf die Seite der Clientanwendung).
  4. Erstellen Sie eine CLR, um auf das entfernte Datenbankobjekt zuzugreifen. Von diesen würde ich wahrscheinlich die CLR verwenden, um auf den entfernten Instanzserver zuzugreifen und die gespeicherte Prozedur auszuführen. Sie müssen das Konto gewähren, das die Quell-SQL Server-Instanz unter Zugriff auf die Remote-SQL Server-Instanz ausführt.
Tom
quelle