EXECUTE AS (cláusula de Transact-SQL)

En SQL Server puede definir el contexto de ejecución de los siguientes módulos definidos por el usuario: funciones (excepto funciones con valores de tabla insertada), procedimientos, colas y desencadenadores.

Al especificar el contexto en el que se ejecuta el módulo, puede controlar qué cuenta de usuario usa Database Engine (Motor de base de datos) para validar permisos en objetos a los que el módulo hace referencia. De esta forma se dispone de mayor control y flexibilidad para administrar los permisos a lo largo de la cadena de objetos que existe entre los módulos definidos por el usuario y los objetos a los que esos módulos hacen referencia. Los permisos deben concederse a usuarios únicamente del propio módulo, sin tener que concederles permisos explícitos en los objetos referenciados. Sólo el usuario que ejecuta el módulo debe tener permisos en los objetos a los que tiene acceso el módulo.

Icono de vínculo a temasConvenciones de sintaxis de Transact-SQL

Sintaxis

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' } 

Argumentos

  • CALLER
    Especifica que las instrucciones dentro del módulo se ejecutan en el contexto del llamador del módulo. El usuario que ejecuta el módulo debe tener los permisos adecuados no sólo en el propio módulo, sino también en los objetos de la base de datos a los que el módulo hace referencia.

    CALLER es el valor predeterminado para todos los módulos excepto las colas, y tiene el mismo comportamiento que SQL Server 2005.

    CALLER no se puede especificar en una instrucción CREATE QUEUE o ALTER QUEUE.

  • SELF
    EXECUTE AS SELF es equivalente a EXECUTE AS user_name, donde el usuario especificado es la persona que crea o modifica el módulo. El Id. de usuario real de la persona que crea o modifica los módulos se almacena en la columna execute_as_principal_id en la vista de catálogo sys.sql_modules o sys.service_queues.

    SELF es el valor predeterminado para colas.

    [!NOTA]

    Para cambiar el Id. de usuario de execute_as_principal_id en la vista de catálogo sys.service_queues, debe especificar de forma explícita el valor de EXECUTE AS en la instrucción ALTER QUEUE.

  • OWNER
    Especifica que las instrucciones dentro del módulo se ejecutan en el contexto del propietario actual del módulo. Si el módulo no tiene un propietario especificado, se usa el propietario del esquema del módulo. OWNER no se puede especificar para los desencadenadores DDL o logon.

    Nota importanteImportante

    OWNER debe asignarse a una cuenta singleton y no puede ser una función o un grupo.

  • 'user_name'
    Especifica que las instrucciones dentro del módulo se ejecutan en el contexto del usuario especificado en user_name. Los permisos para los objetos dentro del módulo se comprueban con user_name. No se puede especificar user_name para desencadenadores DDL con el ámbito de servidor ni para desencadenadores logon. En su lugar, use login_name .

    user_name debe existir en la base de datos actual y debe ser una cuenta singleton. user_name no puede ser un grupo, función, certificado, clave o cuenta integrada, como NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService o NT AUTHORITY\LocalSystem.

    El Id. de usuario del contexto de ejecución se almacena en metadatos y se puede ver en la columna execute_as_principal_id en la vista de catálogo sys.sql_modules o sys.assembly_modules.

  • 'login_name'
    Especifica que las instrucciones dentro del módulo se ejecutan en el contexto del usuario de SQL Server especificado en login_name. Los permisos para los objetos dentro del módulo se comprueban con login_name. Sólo se puede especificar login_name para desencadenadores DDL en el ámbito del servidor o para desencadenadores logon.

    login_name no puede ser un grupo, función, certificado, clave o cuenta integrada, como NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService o NT AUTHORITY\LocalSystem.

Notas

Como Database Engine (Motor de base de datos) evalúa los permisos en los objetos a los que el módulo hace referencia, depende de la cadena de propiedad que existe entre los objetos que llaman y los objetos a los que se hace referencia. En versiones anteriores de SQL Server, la cadena de propiedad era el único método disponible para evitar tener que conceder al usuario que llama acceso a todos los objetos a los que se hace referencia.

La cadena de propiedad tiene las siguientes limitaciones:

  • Sólo se aplica a instrucciones DML: SELECT, INSERT, UPDATE y DELETE.

  • Los propietarios de los objetos que llaman y llamados deben ser los mismos.

  • No se aplica a consultas dinámicas dentro del módulo.

Para obtener más información acerca del encadenamiento de propiedad, vea Cadenas de propiedad.

Independientemente del contexto de ejecución especificado en el módulo, siempre se aplican las siguientes acciones:

  • Cuando se ejecuta el módulo, Database Engine (Motor de base de datos) comprueba primero que el usuario que ejecuta el módulo tiene el permiso EXECUTE en el módulo.

  • Las reglas de la cadena de propiedad siguen aplicándose. Esto significa que si los propietarios de los objetos que llaman y llamados son los mismos, no se comprueban los permisos en los objetos subyacentes.

Cuando un usuario ejecuta un módulo que se ha especificado para ejecutar en un contexto distinto de CALLER, se comprueba el permiso del usuario para ejecutar el módulo, pero también se realizan comprobaciones adicionales de permisos en objetos a los que tiene acceso el módulo contra la cuenta de usuario especificada en la cláusula EXECUTE AS. El usuario que ejecuta el módulo suplanta al usuario especificado.

El contexto especificado en la cláusula EXECUTE AS del módulo sólo es válido durante la ejecución del módulo. El contexto vuelve al llamador cuando finaliza la ejecución del módulo. Para obtener más información acerca del cambio en el contexto de ejecución, vea Usar EXECUTE AS en módulos.

Especificar un nombre de inicio de sesión o usuario

Un usuario de base de datos o un inicio de sesión de servidor especificado en la cláusula EXECUTE AS de un módulo no puede quitarse hasta que el módulo se haya modificado para ejecutarse en otro contexto.

El nombre de inicio de sesión o usuario especificado en la cláusula EXECUTE AS debe existir como una entidad de seguridad en sys.database_principals o sys.server_principals respectivamente, o la operación de creación o modificación del módulo generará errores. Además, el usuario que crea o modifica el módulo debe tener permisos IMPERSONATE en la entidad de seguridad.

Si el usuario tiene acceso implícito a la base de datos o instancia de SQL Server porque pertenece a un grupo de Windows, el usuario especificado en la cláusula EXECUTE AS se crea de forma implícita cuando se crea el módulo y se cumple uno de los siguientes requisitos:

  • El inicio de sesión o usuario especificado es miembro de la función fija de servidor sysadmin.

  • El usuario que crea el módulo tiene permiso para crear entidades de seguridad.

Cuando no se cumple ninguno de esos requisitos, la operación de creación del módulo genera errores.

Nota importanteImportante

Si el servicio (MSSQLSERVER) de SQL Server está ejecutándose como una cuenta local (servicio local o cuenta de usuario local), no tendrá privilegios para obtener la pertenencia a grupo de una cuenta de dominio de Windows especificada en la cláusula EXECUTE AS. Esto generará errores en la ejecución del módulo.

Por ejemplo, supongamos las siguientes condiciones:

  • El grupo CompanyDomain\SQLUsers tiene acceso a la base de datos Sales.

  • CompanyDomain\SqlUser1 es un miembro de SQLUsers y, por tanto, tiene acceso a la base de datos Sales.

  • El usuario que crea o modifica el módulo tiene permisos para crear entidades de seguridad.

Cuando se ejecute la siguiente instrucción CREATE PROCEDURE, el CompanyDomain\SqlUser1 se crea de forma implícita como una entidad de seguridad de la base de datos en la base de datos Sales.

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

Usar la instrucción independiente EXECUTE AS CALLER

Use la instrucción independiente EXECUTE AS CALLER dentro de un módulo para establecer el contexto de ejecución al llamador del módulo.

Suponga que SqlUser2 llama al siguiente procedimiento almacenado.

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

Usar EXECUTE AS para definir conjuntos de permisos personalizados

Cuando desee definir conjuntos de permisos personalizados puede ser muy útil especificar un contexto de ejecución para un módulo. Por ejemplo, algunas acciones, como TRUNCATE TABLE, no tienen permisos que se puedan conceder. Al incorporar la instrucción TRUNCATE TABLE en un módulo y especificar que ese módulo se ejecute con un usuario que tiene permisos para modificar la tabla, puede ampliar los permisos para truncar la tabla al usuario a quien ha concedido permisos EXECUTE en el módulo. Para obtener más información, vea Usar EXECUTE AS para crear conjuntos de permisos personalizados.

Para ver la definición del módulo con el contexto de ejecución especificado, use la vista de catálogo sys.sql_modules (Transact-SQL).

Práctica recomendada

Especifique un inicio de sesión o usuario que tenga al menos los privilegios requeridos para realizar las operaciones definidas en el módulo. Por ejemplo, no especifique una cuenta de propietario de base de datos a menos que tenga los permisos requeridos.

Permisos

Para ejecutar un módulo especificado con EXECUTE AS, el llamador debe tener permisos EXECUTE en el módulo.

Para ejecutar un módulo CLR especificado con EXECUTE AS que tiene acceso a recursos en otra base de datos o servidor, la base de datos o el servidor de destino deben confiar en el autenticador de la base de datos que ha originado el módulo (la base de datos de origen). Para obtener más información acerca de cómo establecer la confianza del autenticador, vea Extender la suplantación de la base de datos mediante EXECUTE AS.

Para especificar la cláusula EXECUTE AS cuando cree o modifique un módulo, debe tener permisos IMPERSONATE en la entidad de seguridad especificada y, además, permisos para crear el módulo. Siempre puede suplantarse a usted mismo. Cuando no se especifica ningún contexto de ejecución o se especifica EXECUTE AS CALLER, no se requieren permisos IMPERSONATE.

Para especificar login_name o user_name que tiene acceso implícito a la base de datos porque pertenece a un grupo de Windows, debe tener permisos CONTROL en la base de datos.

Ejemplos

En el siguiente ejemplo se crea un procedimiento almacenado y se asigna el contexto de ejecución a OWNER.

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

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