EXECUTE AS-Klausel (Transact-SQL)

In SQL Server können Sie den Ausführungskontext der folgenden benutzerdefinierten Module definieren: Funktionen (außer Inline-Tabellenwertfunktionen), Prozeduren, Warteschlangen und Trigger.

Durch Angeben des Kontextes, in dem das Modul ausgeführt wird, können Sie steuern, mit welchem Benutzerkonto Database Engine (Datenbankmodul) Berechtigungen für Objekte, auf die im Modul verwiesen wird, überprüft. Dies bietet zusätzliche Flexibilität und Kontrolle bei der Verwaltung von Berechtigungen für die Objektkette, die zwischen benutzerdefinierten Modulen und den Objekten vorhanden ist, auf die von diesen Modulen verwiesen wird. Berechtigungen müssen nur Benutzern für das Modul selbst erteilt werden, ohne dass ihnen explizite Berechtigungen für die Objekte, auf die verwiesen wird, erteilt werden müssen. Nur das Benutzerkonto, unter dem das Modul ausgeführt wird, benötigt Berechtigungen für die Objekte, auf die das Modul zugreift.

Themenlink (Symbol)Transact-SQL-Syntaxkonventionen

Syntax

Functions (except inline table-valued functions), Stored Procedures, and DML Triggers
{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' } 

DDL Triggers with Database Scope
{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' } 

DDL Triggers with Server Scope and logon triggers
{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' } 

Queues
{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' } 

Argumente

  • CALLER
    Gibt an, dass die Anweisungen innerhalb des Moduls im Kontext des Aufrufers des Moduls ausgeführt werden. Der Benutzer, der das Modul ausführt, benötigt die entsprechenden Berechtigungen nicht nur für das Modul selbst, sondern auch für alle Datenbankobjekte, auf die das Modul verweist.

    CALLER ist der Standardwert für alle Module außer Warteschlangen, was dem Verhalten von SQL Server 2005 entspricht.

    CALLER kann in einer CREATE QUEUE- oder ALTER QUEUE-Anweisung nicht angegeben werden.

  • SELF
    EXECUTE AS SELF ist gleichbedeutend mit EXECUTE AS user_name, wobei der angegebene Benutzer die Person ist, die das Modul erstellt oder ändert. Die eigentliche Benutzer-ID der Person, die die Module erstellt oder ändert, wird in der execute_as_principal_id-Spalte der sys.sql_modules- oder sys.service_queues-Katalogsicht gespeichert.

    SELF ist der Standardwert für Warteschlangen.

    HinweisHinweis

    Zum Ändern der Benutzer-ID von execute_as_principal_id in der sys.service_queues-Katalogsicht müssen Sie explizit die EXECUTE AS-Einstellung in der ALTER QUEUE-Anweisung angeben.

  • OWNER
    Gibt an, dass die Anweisungen innerhalb des Moduls im Kontext des aktuellen Besitzers des Moduls ausgeführt werden. Falls für das Modul kein Besitzer angegeben ist, wird der Besitzer des Modulschemas verwendet. OWNER kann für DDL- oder LOGON-Trigger nicht angegeben werden.

    Wichtiger HinweisWichtig

    OWNER muss einem Singleton-Konto zugewiesen werden und darf keine Rolle oder Gruppe sein.

  • 'user_name'
    Gibt an, dass die Anweisungen innerhalb des Moduls im Kontext des in user_name angegebenen Kontextes ausgeführt werden. Berechtigungen für Objekte innerhalb des Moduls werden anhand von user_name überprüft. user_name kann für DDL-Trigger mit Serverbereich oder LOGON-Trigger nicht angegeben werden. Verwenden Sie stattdessen login_name .

    user_name muss in der aktuellen Datenbank vorhanden sein und muss ein Singleton-Konto sein. user_name kann kein(e) Gruppe, Rolle, Zertifikat, Schlüssel oder integriertes Konto sein, wie z. B. NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService oder NT AUTHORITY\LocalSystem.

    Die Benutzer-ID des Ausführungskontextes wird in Metadaten gespeichert und kann in der execute_as_principal_id-Spalte der sys.sql_modules- oder sys.assembly_modules-Katalogsicht angezeigt werden.

  • 'login_name'
    Gibt an, dass die Anweisungen innerhalb des Moduls im Kontext des in login_name angegebenen SQL Server-Anmeldenamens ausgeführt werden. Berechtigungen für Objekte innerhalb des Moduls werden anhand von login_name überprüft. login_name kann nur für DDL-Trigger mit Serverbereich oder LOGON-Trigger angegeben werden.

    login_name kann kein(e) Gruppe, Rolle, Zertifikat, Schlüssel oder integriertes Konto sein, wie z. B. NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService oder NT AUTHORITY\LocalSystem.

Hinweise

Wie Database Engine (Datenbankmodul) Berechtigungen für Objekte auswertet, auf die im Modul verwiesen wird, hängt von der Besitzkette ab, die zwischen den aufrufenden Objekten und den Objekten vorhanden ist, auf die verwiesen wird. In früheren Versionen von SQL Server war die Besitzverkettung die einzig verfügbare Methode, um zu vermeiden, dass dem aufrufenden Benutzer der Zugriff für alle Objekte, auf die verwiesen wird, erteilt werden muss.

Für die Besitzverkettung gelten die folgenden Einschränkungen:

  • Gilt nur für DML-Anweisungen: SELECT, INSERT, UPDATE und DELETE.

  • Die Besitzer der aufrufenden Objekte und der aufgerufenen Objekte, müssen identisch sein.

  • Gilt nicht für dynamische Abfragen innerhalb des Moduls.

Weitere Informationen zur Besitzverkettung finden Sie unter Besitzketten.

Die folgenden Aktionen werden immer angewendet, unabhängig vom Ausführungskontext, der im Modul angegeben ist:

  • Wenn das Modul ausgeführt wird, überprüft Database Engine (Datenbankmodul) zunächst, ob der Benutzer, der das Modul ausführt, die EXECUTE-Berechtigung für das Modul besitzt.

  • Besitzverkettungsregeln werden weiterhin angewendet. Das heißt, wenn die Besitzer der aufrufenden und der aufgerufenen Objekte identisch sind, werden keine Berechtigungen der zugrunde liegenden Objekte überprüft.

Wenn ein Benutzer ein Modul ausführt, für das die Ausführung in einem anderen Kontext als CALLER definiert wurde, wird die Berechtigung des Benutzers zum Ausführen des Moduls überprüft. Zusätzliche Berechtigungsüberprüfungen für Objekte, auf die das Modul zugreift, werden jedoch für das Benutzerkonto ausgeführt, das in der EXECUTE AS-Klausel angegeben ist. Der Benutzer, der das Modul ausführt, nimmt die Identität des angegebenen Benutzers an.

Der in der EXECUTE AS-Klausel des Moduls angegebene Kontext ist nur während der Ausführung des Moduls gültig. Der Kontext des Aufrufers wird wiederhergestellt, wenn die Ausführung des Moduls abgeschlossen ist. Weitere Informationen zum Wechseln des Ausführungskontextes finden Sie unter Verwenden von EXECUTE AS in Modulen.

Angeben eines Benutzers oder eines Anmeldenamens

Ein Datenbankbenutzer oder Serveranmeldename, der in der EXECUTE AS-Klausel eines Moduls angegeben ist, kann erst gelöscht werden, wenn das Modul zur Ausführung unter einem anderen Kontext geändert wird.

Der in der EXECUTE AS-Klausel angegebene Benutzer oder Anmeldename muss als Prinzipal in sys.database_principals bzw. sys.server_principals vorhanden sein. Andernfalls wird für den Vorgang zum Erstellen oder Ändern des Moduls ein Fehler gemeldet. Darüber hinaus benötigt der Benutzer, der das Modul erstellt oder ändert, IMPERSONATE-Berechtigungen für den Prinzipal.

Falls der Benutzer impliziten Zugriff auf die Datenbank oder Instanz von SQL Server über eine Windows-Gruppenmitgliedschaft hat, wird der in der EXECUTE AS-Klausel angegebene Benutzer beim Erstellen des Moduls implizit erstellt. Dazu muss eine der folgenden Anforderungen erfüllt sein:

  • Der angegebene Benutzer oder Anmeldename ist ein Mitglied der festen Serverrolle sysadmin.

  • Der Benutzer, der das Modul erstellt, hat die Berechtigung zum Erstellen von Prinzipalen.

Wenn keine dieser Anforderungen erfüllt ist, wird für den Vorgang zum Erstellen des Moduls ein Fehler gemeldet.

Wichtiger HinweisWichtig

Wenn der SQL Server (MSSQLSERVER)-Dienst als lokales Konto (lokaler Dienst oder lokales Benutzerkonto) ausgeführt wird, hat er keine Privilegien zum Erhalten der Gruppenmitgliedschaften eines Windows-Domänenkontos, das in der EXECUTE AS-Klausel angegeben ist. Deshalb wird die Ausführung des Moduls fehlschlagen.

Stellen Sie sich z. B. folgende Bedingungen vor:

  • Die CompanyDomain\SQLUsers-Gruppe hat Zugriff auf die Sales-Datenbank.

  • CompanyDomain\SqlUser1 ist ein Mitglied von SQLUsers und hat deshalb Zugriff auf die Sales-Datenbank.

  • Der Benutzer, der das Modul erstellt oder ändert, hat Berechtigungen zum Erstellen von Prinzipalen.

Wenn die folgende CREATE PROCEDURE-Anweisung ausgeführt wird, wird CompanyDomain\SqlUser1 als Datenbankprinzipal in der Sales-Datenbank erstellt.

USE Sales;
GO
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT user_name();
GO

Verwenden der eigenständigen EXECUTE AS CALLER-Anweisung

Verwenden Sie die eigenständige EXECUTE AS CALLER-Anweisung innerhalb eines Moduls, um den Ausführungskontext auf den Aufrufer des Moduls festzulegen.

Angenommen, die folgende gespeicherte Prozedur wird von SqlUser2 aufgerufen.

CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'SqlUser1'
AS
SELECT user_name(); -- Shows execution context is set to SqlUser1.
EXECUTE AS CALLER;
SELECT user_name(); -- Shows execution context is set to SqlUser2, the caller of the module.
REVERT;
SELECT user_name(); -- Shows execution context is set to SqlUser1.
GO

Verwenden von EXECUTE AS zum Definieren benutzerdefinierter Berechtigungssätze

Das Angeben eines Ausführungskontextes für ein Modul kann äußerst hilfreich sein, wenn Sie benutzerdefinierte Berechtigungssätze definieren möchten. Beispielsweise weisen bestimmte Aktionen wie etwa TRUNCATE TABLE keine erteilbaren Berechtigungen auf. Sie können die TRUNCATE TABLE-Anweisung innerhalb eines Moduls integrieren und angeben, dass dieses Modul als Benutzer mit Berechtigungen zum Ändern der Tabelle ausgeführt wird. Dadurch können Sie die Berechtigungen zum Abschneiden der Tabelle auf den Benutzer erweitern, dem Sie EXECUTE-Berechtigungen für das Modul erteilen. Weitere Informationen finden Sie unter Verwenden von EXECUTE AS zum Erstellen benutzerdefinierter Berechtigungssätze.

Verwenden Sie die sys.sql_modules (Transact-SQL)-Katalogsicht, um die Definition des Moduls mit dem angegebenen Ausführungskontext anzuzeigen.

Bewährte Methoden

Geben Sie einen Anmeldenamen oder einen Benutzer an, der die mindestens erforderlichen Privilegien zum Ausführen der im Modul definierten Vorgänge aufweist. Geben Sie z. B. kein Datenbankbesitzer-Konto an, außer diese Berechtigungen sind erforderlich.

Berechtigungen

Für die Ausführung eines mit EXECUTE AS angegebenen Moduls benötigt der Aufrufer EXECUTE-Berechtigungen für das Modul.

Für die Ausführung eines mit EXECUTE AS angegebenen CLR-Moduls, das auf Ressourcen in einer anderen Datenbank oder auf einem anderen Server zugreift, muss die Zieldatenbank oder der Server dem Authentifikator der Datenbank vertrauen, aus der das Modul stammt (die Quelldatenbank). Weitere Informationen zum Einrichten einer Authentifikatorvertrauensstellung finden Sie unter Erweitern des Identitätswechsels bei Datenbanken durch Verwenden von EXECUTE AS.

Zum Angeben der EXECUTE AS-Klausel beim Erstellen oder Ändern eines Moduls benötigen Sie IMPERSONATE-Berechtigungen für den angegebenen Prinzipal sowie Berechtigungen zum Erstellen des Moduls. Sie können immer Ihre eigene Identität annehmen. Wenn kein Ausführungskontext angegeben ist oder wenn EXECUTE AS CALLER angegeben ist, sind keine IMPERSONATE-Berechtigungen erforderlich.

Um einen login_name oder user_name anzugeben, der über eine Windows-Gruppenmitgliedschaft impliziten Zugriff auf die Datenbank hat, benötigen Sie CONTROL-Berechtigungen für die Datenbank.

Beispiele

Im folgenden Beispiel wird eine gespeicherte Prozedur erstellt und der Ausführungskontext OWNER zugewiesen.

USE AdventureWorks2008R2;
GO
CREATE PROCEDURE HumanResources.uspEmployeesInDepartment 
@DeptValue int
WITH EXECUTE AS OWNER
AS
    SET NOCOUNT ON;
    SELECT e.BusinessEntityID, c.LastName, c.FirstName, e.JobTitle
    FROM Person.Person AS c 
    INNER JOIN HumanResources.Employee AS e
        ON c.BusinessEntityID = e.BusinessEntityID
    INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
        ON e.BusinessEntityID = edh.BusinessEntityID
    WHERE edh.DepartmentID = @DeptValue
    ORDER BY c.LastName, c.FirstName;
GO

-- Execute the stored procedure by specifying department 5.
EXECUTE HumanResources.uspEmployeesInDepartment 5;
GO