EXECUTE AS (cláusula de Transact-SQL)

Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance

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 insertadas), procedimientos, colas y desencadenadores.

Al especificar el contexto en el que se ejecuta el módulo, puede controlar qué cuenta de usuario usa 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 para los objetos referenciados. Solo el usuario que ejecuta el módulo debe tener permisos en los objetos a los que tiene acceso el módulo.

Convenciones de sintaxis de Transact-SQL

Sintaxis

En esta sección se describe la sintaxis de SQL Server para EXECUTE AS.

Funciones (excepto funciones con valores de tabla insertados), procedimientos almacenados y desencadenadores DML:

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

Desencadenadores DDL con ámbito de base de datos:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }

Desencadenadores DDL con el ámbito del servidor y desencadenadores de inicio de sesión:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }

Colas:

{ 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 solo 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 es el mismo que el comportamiento de SQL Server 2005 (9.x).

CALLER no se puede especificar en una CREATE QUEUE instrucción 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 identificador de usuario real de la persona que crea o modifica los módulos se almacena en la columna en la execute_as_principal_id sys.sql_modules vista de catálogo o sys.service_queues .

SELF es el valor predeterminado para las colas.

Nota:

Para cambiar el identificador de usuario de la execute_as_principal_id columna en la vista de sys.service_queues catálogo, debe especificar explícitamente la EXECUTE AS configuración en la ALTER QUEUE instrucción .

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 desencadenadores DDL o de inicio de sesión.

Importante

OWNER debe asignarse a una cuenta singleton y no puede ser un rol o 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. user_name no se pueden especificar para desencadenadores DDL con desencadenadores de ámbito de servidor o desencadenadores de inicio de sesión. Use login_name en su lugar.

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

El identificador de usuario del contexto de ejecución se almacena en metadatos y se puede ver en la columna en la execute_as_principal_id sys.sql_modules vista de catálogo 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 que haya dentro del módulo se comprueban con login_name. login_name se puede especificar únicamente para desencadenadores DDL con el ámbito de servidor o para desencadenadores de inicio de sesión.

login_name no puede ser un grupo, rol, certificado, clave o cuenta integrada, como NT AUTHORITY\LocalService, NT AUTHORITY\NetworkServiceo NT AUTHORITY\LocalSystem.

Comentarios

Como 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:

  • Solo se aplica a instrucciones DML: SELECT, INSERT, UPDATEy DELETE.
  • Los propietarios de los objetos que llaman y llamados deben ser los mismos.
  • No se aplica a las consultas dinámicas dentro del módulo.

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

  • Cuando se ejecuta el módulo, el Motor de base de datos comprueba primero que el usuario que ejecuta el módulo tiene EXECUTE permiso 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 ejecutarse en un contexto distinto CALLERde , se comprueba el permiso del usuario para ejecutar el módulo, pero se comprueban comprobaciones de permisos adicionales en los objetos a los que accede el módulo en la cuenta de usuario especificada en la EXECUTE AS cláusula . El usuario que ejecuta el módulo suplanta al usuario especificado.

El contexto especificado en la EXECUTE AS cláusula del módulo solo es válido durante la ejecución del módulo. El contexto vuelve al llamador cuando finaliza la ejecución del módulo.

Especificar un nombre de usuario o de inicio de sesión

No se puede quitar un usuario de base de datos o un inicio de sesión de servidor especificado en la EXECUTE AS cláusula de un módulo hasta que se modifique el módulo para que se ejecute en otro contexto.

El nombre de usuario o de inicio de sesión especificado en la EXECUTE AS cláusula debe existir como entidad de seguridad en sys.database_principals o sys.server_principals, respectivamente, o bien se produce un error en la operación de creación o modificación del módulo. 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 a través de una pertenencia a grupos de Windows, el usuario especificado en la EXECUTE AS cláusula se crea implícitamente cuando se crea el módulo cuando existe uno de los siguientes requisitos:

  • El inicio de sesión o usuario especificado es miembro del rol fijo 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.

Importante

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

Por ejemplo, supongamos las siguientes condiciones:

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

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

  • 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

Uso de la instrucción independiente EXECUTE AS CALLER

Use la EXECUTE AS CALLER instrucción independiente dentro de un módulo para establecer el contexto de ejecución en el autor de la llamada 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

Uso de EXECUTE AS para definir conjuntos de permisos personalizados

Especificar un contexto de ejecución para un módulo puede ser útil cuando se quieren definir conjuntos de permisos personalizados. Por ejemplo, algunas acciones, como TRUNCATE TABLE no tienen permisos concedidos. Al incorporar la TRUNCATE TABLE instrucción dentro de un módulo y especificar que el módulo se ejecute como un usuario que tenga permisos para modificar la tabla, puede ampliar los permisos para truncar la tabla al usuario al que concede EXECUTE permisos en el módulo.

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).

Procedimiento recomendado

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 la base de datos a menos que se requieran esos permisos.

Permisos

Para ejecutar un módulo especificado con EXECUTE AS, el autor de la llamada debe tener EXECUTE permisos en el módulo.

Para ejecutar un módulo CLR especificado con EXECUTE AS que accede a los recursos de otra base de datos o servidor, la base de datos de destino o el servidor deben confiar en el autenticador de la base de datos desde la que se origina el módulo (la base de datos de origen).

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

Para especificar un login_name o user_name que tenga acceso implícito a la base de datos a través de una pertenencia a grupos de Windows, debe tener CONTROL permisos en la base de datos.

Ejemplos

En el ejemplo siguiente se crea un procedimiento almacenado en la base de datos AdventureWorks2022 y se asigna el contexto de ejecución a OWNER.

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