EXECUTE AS, предложение (Transact-SQL)

Область применения: yesSQL Server (все поддерживаемые версии) YesБаза данных SQL Azure YesУправляемый экземпляр SQL Azure

В SQL Server можно определять контекст выполнения для следующих определяемых пользователем модулей: функций (за исключением встроенных функций с табличным значением), процедур, очередей и триггеров.

Указывая контекст, в котором выполняется модуль, можно управлять тем, какую учетную запись компонента Компонент Database Engine использует при проверке разрешений на объекты, на которые ссылается модуль. Это повышает гибкость и безопасность управления разрешениями на цепочки владения между пользовательскими модулями и объектами, на которые они ссылаются. Тогда пользователям необходимо будет предоставлять только разрешения на сам модуль, без выдачи явных разрешений на объекты, на которые он ссылается. Только пользователь, от имени которого выполняется модуль, должен будет иметь разрешения на объекты, к которым этот модуль обращается.

Topic link iconСинтаксические обозначения в Transact-SQL

Синтаксис

-- SQL Server 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' }   
-- Azure SQL Database 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' }  
  

Примечание

Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.

Аргументы

CALLER
Указывает, что инструкции, содержащиеся в модуле, выполняются в контексте пользователя, вызывающего этот модуль. Пользователь, выполняющий модуль, должен иметь соответствующие разрешения не только на сам модуль, но также и на объекты базы данных, на которые имеются ссылки из этого модуля.

Аргумент CALLER является значением по умолчанию для всех модулей, кроме очередей, и работает так же, как и в SQL Server 2005 (9.x).

Ключевое слово CALLER не может быть указано в инструкции CREATE QUEUE или ALTER QUEUE.

SELF
EXECUTE AS SELF эквивалентно EXECUTE AS user_name, где указанный пользователь — это тот, кто создает или изменяет модуль. Фактический идентификатор пользователя, создающего или изменяющего модуль, хранится в столбце execute_as_principal_id в представлении каталога sys.sql_modules или sys.service_queues.

Аргумент SELF является значением по умолчанию для очередей.

Примечание

Чтобы изменить идентификатор пользователя в execute_as_principal_id представления каталога sys.service_queues, необходимо явно указать аргумент EXECUTE AS в инструкции ALTER QUEUE.

OWNER
Указывает, что инструкции, содержащиеся в модуле, выполняются в контексте текущего владельца этого модуля. Если для модуля не определен владелец, то подразумевается владелец схемы модуля. Ключевое слово OWNER не может указываться для триггеров DDL или триггеров входа.

Важно!

OWNER должен быть сопоставлен с негрупповой учетной записью и не может быть ролью или группой.

'user_name'
Указывает, что инструкции, содержащиеся в модуле, выполняются в контексте пользователя, указываемого аргументом user_name. Разрешения на объекты, на которые ссылается модуль, проверяются для user_name. Аргумент user_name нельзя указывать для триггеров DDL в области сервера или триггеров входа. Вместо него следует использовать login_name.

Аргумент user_name должен присутствовать в текущей базе данных и не должен относиться к учетной записи группы. В качестве аргумента user_name не могут быть указаны роль, сертификат, ключ или встроенная учетная запись (например, NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService или NT AUTHORITY\LocalSystem).

Идентификатор пользователя контекста выполнения хранится в метаданных, его можно получить из столбца execute_as_principal_id представления каталога sys.sql_modules или sys.assembly_modules.

'login_name'
Указывает, что инструкции, содержащиеся в модуле, выполняются в контексте имени входа SQL Server, указанного в аргументе login_name. Разрешения на объекты, на которые ссылается модуль, проверяются для login_name. Аргумент login_name можно указывать только для триггеров DDL в области сервера или триггеров входа.

В качестве аргумента login_name не могут быть указаны роль, сертификат, ключ или встроенная учетная запись (например, NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService или NT AUTHORITY\LocalSystem).

Комментарии

Способ, которым компонент Компонент Database Engine определяет разрешения на объекты, зависит от цепочки владения, связывающей модуль и объекты, на который он ссылается. В предыдущих версиях SQL Server цепочки владения были единственным методом, который позволял избежать предоставления пользователю разрешений на все объекты, к которым модуль производит доступ.

Цепочки владения имеют следующие ограничения.

  • Применяются только к инструкциям DML: SELECT, INSERT, UPDATE и DELETE.

  • У вызывающего и вызываемого объекта должен быть один и тот же владелец.

  • Не применяются к динамическим запросам в модуле.

Независимо от контекста выполнения, указанного в модуле, всегда выполняются следующие действия.

  • Компонент Компонент Database Engine сначала проверяет, имеет ли пользователь, выполняющий модуль, разрешение EXECUTE на него.

  • Применяются правила цепочки владения, то есть если вызывающий и вызываемый объекты имеют одного и того же владельца, разрешения на вложенные объекты не проверяются.

Если пользователь выполняет модуль, для которого определен запуск в контексте, отличном от CALLER, проверяются разрешения пользователя на выполнение модуля, а проверки разрешений на объекты, к которым модуль производит доступ, выполняются для учетной записи пользователя, указанной в предложении EXECUTE AS. Пользователь, выполняющий модуль, таким образом олицетворяет указанного пользователя.

Контекст, указанный в предложении EXECUTE AS, действует только до конца выполнения модуля, после чего производится возврат в исходный контекст.

Указание имени пользователя или имени входа

Пользователь базы данных и имя входа сервера, указанные в предложении EXECUTE AS, не могут быть удалены до тех пор, пока модуль не будет изменен так, чтобы он выполнялся в другом контексте.

Имя пользователя или имя входа, указанное в предложении EXECUTE AS, должно присутствовать в качестве участника в sys.database_principals или sys.server_principals соответственно; в противном случае операция создания или изменения модуля завершается ошибкой. К тому же пользователь, который создает или изменяет модуль, должен иметь разрешение IMPERSONATE на этого участника.

Если пользователь неявно имеет доступ к базе данных или экземпляру SQL Server через членство в группе Windows, то пользователь, указанный в предложении EXECUTE AS, неявно создается в момент создания модуля при соблюдении следующих условий.

  • Указанный пользователь или имя входа является членом предопределенной роли сервера sysadmin.

  • Пользователь, который создает модуль, имеет разрешение на создание участников.

Если какое-либо из этих условий не соблюдается, операция создания модуля завершается ошибкой.

Важно!

Если служба SQL Server (MSSQLSERVER) выполняется от имени локальной учетной записи (локальной службы или локального пользователя), она не будет иметь прав на членство в группах домена Windows, которые могут быть указаны в предложении EXECUTE AS. Это приведет к ошибке выполнения модуля.

Для примера рассмотрим следующие условия.

  • Группа CompanyDomain\SQLUsers имеет доступ к базе данных Sales.

  • CompanyDomain\SqlUser1 является членом SQLUsers и, таким образом, имеет доступ к базе данных Sales.

  • Пользователь, который создает модуль, имеет разрешение на создание участников.

Когда следующее выражение CREATE PROCEDURE выполняется, выражение CompanyDomain\SqlUser1 безоговорочно создается в качестве базы данных субъекта в базе данных Sales .

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

Использование EXECUTE AS CALLER в качестве изолированной инструкции

EXECUTE AS CALLER можно выполнять в модуле в качестве изолированной инструкции для переключения контекста на пользователя, вызывающего модуль.

Рассмотрим следующую хранимую процедуру под названием SqlUser2.

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  

Применение EXECUTE AS для определения пользовательских наборов разрешений

Выбор контекста выполнения в модуле может оказаться полезным в тех случаях, когда необходимо определить пользовательский набор разрешений. Для некоторых действий (например, TRUNCATE TABLE) соответствующие разрешения не реализованы. Включив инструкцию TRUNCATE TABLE в модуль и определив выполнение этого модуля от имени пользователя, который имеет разрешение на изменение таблицы, можно передавать возможность усечения таблицы другим пользователям, предоставляя им разрешение EXECUTE на этот модуль.

Для просмотра определения модуля вместе с указанием контекста выполнения воспользуйтесь представлением каталога sys.sql_modules (Transact-SQL).

Рекомендации

Указывайте имя входа или пользователя, имеющего минимальные права на выполнение операций, определенных в модуле. Например, указывайте учетную запись владельца базы данных только тогда, когда разрешения, которыми он обладает, действительно необходимы.

Разрешения

Для выполнения модуля с указанным предложением EXECUTE AS пользователь должен иметь разрешение EXECUTE на модуль.

Для выполнения указанного с предложением EXECUTE AS модуля CLR, который производит доступ к ресурсам в другой базе данных или на другом сервере, целевым сервером или базой данных должно быть выдано удостоверение проверки подлинности для базы данных, в которой находится модуль (т.е. базы данных-источника).

Для указания предложения EXECUTE AS при создании или изменении модуля необходимо разрешение IMPERSONATE на указанного участника, а также разрешение на создание модуля. Пользователь всегда может олицетворять сам себя. Если контекст выполнения не указан или указано EXECUTE AS CALLER, разрешение IMPERSONATE не требуется.

Для указания login_name или user_name, которые неявно имеют доступ к базе данных посредством членства в группе Windows, требуется разрешение CONTROL в базе данных.

Примеры

В следующем примере создается хранимая процедура в базе данных AdventureWorks2012, которой затем назначается контекст выполнения 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  

См. также

sys.assembly_references (Transact-SQL)
sys.sql_modules (Transact-SQL)
sys.service_queues (Transact-SQL)
REVERT (Transact-SQL)
EXECUTE AS (Transact-SQL)