EXECUTE AS (Transact-SQL)
Задает контекст выполнения для сеанса.
По умолчанию сеанс запускается при входе пользователя в систему и завершается при выходе пользователя из системы. Все операции во время сеанса подлежат проверке на наличие у пользователя соответствующих разрешений. При запуске инструкции EXECUTE AS контекст выполнения сеанса переключается на заданное имя входа или имя пользователя. После переключений контекста имя входа и пользовательские токены безопасности для этой учетной записи проходят проверку на соответствие разрешениям (а не пользователь, вызвавший инструкцию EXECUTE AS). В сущности, либо входная или пользовательская учетная запись олицетворяется на время сеанса или на время выполнения модуля, либо явно обращается переключение контекста.
Применимо для следующих объектов: SQL Server (SQL Server 2008 по текущую версию), База данных SQL Windows Azure (С первоначального выпуска по текущий выпуск). |
Синтаксические обозначения в Transact-SQL
Синтаксис
{ EXEC | EXECUTE } AS <context_specification>
[;]
<context_specification>::=
{ LOGIN | USER } = 'name'
[ WITH { NO REVERT | COOKIE INTO @varbinary_variable } ]
| CALLER
Аргументы
LOGIN
Применимо для следующих объектов: С SQL Server 2008 по SQL Server 2014 включительно.
Указывает, что контекст выполнения олицетворения — это имя входа. Область олицетворения — это уровень сервера.
Примечание
Этот параметр недоступен в автономной базе данных.
USER
Определяет контекст для олицетворения пользователя в текущей базе данных. Область олицетворения ограничена текущей базой данных. При переключении контекста на пользователя базы данных разрешения уровня сервера этого пользователя не наследуются.Важно! Пока переключение контекста на пользователя базы данных активно, любая попытка подключиться к ресурсам вне базы данных будет приводить к завершению инструкции с ошибками.Это касается инструкций USE database, распределенных запросов, а также запросов, которые ссылаются на другую базу данных, использующую трех- и четырехчастные идентификаторы.
' name '
Допустимое имя пользователя или имя входа. name должен быть членом предопределенной роли сервера sysadmin или быть участником sys.database_principals или sys.server_principals соответственно.name можно задавать как локальную переменную.
Учетная запись name должна быть одноэлементной и не может быть группой, ролью, сертификатом, ключом или встроенной учетной записью, например NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService или NT AUTHORITY\LocalSystem.
Дополнительные сведения см. в разделе Указание имени пользователя или имени входа далее.
NO REVERT
Указывает, что переключение контекста нельзя вернуть к предыдущему контексту. Параметр NO REVERT можно использовать только на нерегламентированном уровне.Дополнительные сведения о переключении к предыдущему контексту см. в разделе REVERT (Transact-SQL).
COOKIE INTO **@**varbinary_variable
Указывает, что контекст выполнения можно переключить к предыдущему контексту, если при вызове инструкция REVERT WITH COOKIE содержит правильное значение **@**varbinary_variable . Компонент Компонент Database Engine передает куки-файл **@**varbinary_variable. Параметр COOKIE INTO можно использовать только на нерегламентированном уровне.Аргумент **@**varbinary_variable имеет тип varbinary(8000).
Примечание
Параметр OUTPUT куки-файла в настоящее время описан в документации как varbinary(8000), что верно определяет его максимальную длину.Однако текущая реализация возвращает varbinary(100).Для продолжения правильной работы в случае увеличения размера куки-файлов в последующих версиях в приложении должен быть зарезервирован тип varbinary(8000).
CALLER
При использовании внутри модуля указывает, что инструкции модуля выполняются в контексте вызывающей стороны.При использовании вне модуля инструкция не действует.
Замечания
Изменение в контексте выполнения продолжает действовать до тех пор, пока не произойдет одно из следующих событий.
Будет запущена еще одна инструкция EXECUTE AS.
Будет запущена инструкция REVERT.
Сеанс удаляется.
Выход из хранимой процедуры или триггера, где была выполнена команда.
Набор контекстов выполнения может быть создан при помощи нескольких вызовов инструкции EXECUTE AS на нескольких участниках. При вызове инструкция REVERT производит переключение контекста на имя входа или на пользователя на более высоком уровне стека контекстов. Это показано в разделе Пример А.
Указание пользователя или имени входа
Имя пользователя или имя входа, указанное в инструкции EXECUTE AS <context_specification>, должно быть участником в базе данных sys.database_principals или sys.server_principals соответственно, в противном случае инструкция EXECUTE AS будет завершена с ошибками. Кроме того, этому участнику должны быть предоставлены разрешения IMPERSONATE. Если вызывающая сторона не является владельцем базы данных или членом предопределенной роли сервера sysadmin, то участник должен существовать даже тогда, когда пользователь обращается к базе данных или к экземпляру SQL Server в качестве члена группы Windows. Для примера рассмотрим следующие условия.
группа CompanyDomain\SQLUsers имеет доступ к базе данных Sales;
CompanyDomain\SqlUser1 является членом SQLUsers и поэтому имеет открытый доступ к базе данных Sales.
Хотя CompanyDomain\SqlUser1 имеет доступ к базе данных с помощью членства в группе SQLUsers, инструкция EXECUTE AS USER = 'CompanyDomain\SqlUser1' завершается с ошибками, поскольку CompanyDomain\SqlUser1 не является участником в базе данных.
Если пользователь утратил связь с учетной записью (соответствующее имя входа больше не существует) и пользователь не был создан с параметром WITHOUT LOGIN, попытка этого пользователя выполнить команду EXECUTE AS завершится неудачно.
Рекомендация
Указывайте имя входа или пользователя, который имеет наименьшие права доступа, необходимые для выполнения операций в сеансе. Например, не указывайте имя входа с разрешениями уровня сервера, если требуются разрешения только уровня базы данных, а также не указывайте учетную запись владельца базы данных, если только эти разрешения не являются обязательными.
Предупреждение
Инструкция EXECUTE AS может выполняться успешно, пока компонент Компонент Database Engine может разрешить имя.Если пользователь в домене существует, Windows может разрешить доступ в компоненте Компонент Database Engine пользователю, даже если у пользователя Windows отсутствует доступ к SQL Server.Данное обстоятельство может привести к ситуации, когда пользователь, не имеющий доступа к SQL Server, сможет войти в систему, хотя олицетворенное имя входа будет иметь только те разрешения, которые предоставлены пользователю public или guest.
Применение WITH NO REVERT
Если инструкция EXECUTE AS содержит необязательное предложение WITH NO REVERT, то контекст выполнения для сеанса нельзя сбросить с помощью инструкции REVERT или путем выполнения другой инструкции EXECUTE AS. Контекст, заданный инструкцией, остается до удаления сеанса.
Если указано предложение WITH NO REVERT COOKIE = @varbinary\_variabl, то Компонент SQL Server Database Engine передает значение куки-файла в @varbinary\_variable. Контекст выполнения, устанавливаемый данной инструкцией, можно возвратить только к предыдущему контексту, если вызов инструкции REVERT WITH COOKIE = @varbinary\_variable содержит такое же значение @varbinary\_variable .
Этот параметр может пригодиться в среде с организацией пула соединений. Организация пула соединений — это поддержка группы подключений к базе данных для повторного использования приложениями или сервером приложений. Поскольку значение, передаваемое в @varbinary\_variable, известно только инициатору инструкции EXECUTE AS, то инициатор может гарантировать, что установленный им контекст выполнения больше никто не сможет изменить.
Определение первоначального имени входа
Функция ORIGINAL_LOGIN возвращает имя входа, которое подключилось к экземпляру SQL Server. Можно использовать эту функцию для возврата идентификатора исходного имени входа в сеансах, содержащих множество явных и неявных переключений контекста.
Разрешения
Чтобы указать параметр EXECUTE AS при входе, у вызывающего пользователя должно быть разрешение IMPERSONATE для заданного имени входа и не должно быть запрещено разрешение IMPERSONATE ANY LOGIN. Чтобы указать в предложении EXECUTE AS пользователя базы данных, вызывающая сторона должна иметь разрешения IMPERSONATE на указанное имя входа. Если указан параметр EXECUTE AS CALLER, то разрешения IMPERSONATE не являются обязательными.
Примеры
А.Использование предложений EXECUTE AS и REVERT для переключения контекста
В приведенном примере создается стек контекстов выполнения с использованием нескольких участников. Затем инструкция REVERT используется для сброса контекста выполнения к предыдущему участнику. Инструкция REVERT выполняется множество раз, передвигаясь вверх по стеку до тех пор, пока контекст выполнения не будет установлен на первоначального участника.
USE AdventureWorks2012;
GO
--Create two temporary principals
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
GO
CREATE USER user1 FOR LOGIN login1;
CREATE USER user2 FOR LOGIN login2;
GO
--Give IMPERSONATE permissions on user2 to user1
--so that user1 can successfully set the execution context to user2.
GRANT IMPERSONATE ON USER:: user2 TO user1;
GO
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- Set the execution context to login1.
EXECUTE AS LOGIN = 'login1';
--Verify the execution context is now login1.
SELECT SUSER_NAME(), USER_NAME();
--Login1 sets the execution context to login2.
EXECUTE AS USER = 'user2';
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- The execution context stack now has three principals: the originating caller, login1 and login2.
--The following REVERT statements will reset the execution context to the previous context.
REVERT;
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
REVERT;
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
--Remove temporary principals.
DROP LOGIN login1;
DROP LOGIN login2;
DROP USER user1;
DROP USER user2;
GO
Б.Использование предложения WITH COOKIE
Следующий образец устанавливает контекст выполнения сеанса для определенного пользователя и указывает предложение WITH NO REVERT COOKIE = @varbinary\_variable. Инструкция REVERT обязана указать значение, передаваемое переменной @cookie в EXECUTE AS инструкции, для успешного возвращения контекста обратно вызывающему. Чтобы запустить этот образец, должно существовать имя входа login1 и пользователь user1, созданные в примере А.
DECLARE @cookie varbinary(8000);
EXECUTE AS USER = 'user1' WITH COOKIE INTO @cookie;
-- Store the cookie in a safe location in your application.
-- Verify the context switch.
SELECT SUSER_NAME(), USER_NAME();
--Display the cookie value.
SELECT @cookie;
GO
-- Use the cookie in the REVERT statement.
DECLARE @cookie varbinary(8000);
-- Set the cookie value to the one from the SELECT @cookie statement.
SET @cookie = <value from the SELECT @cookie statement>;
REVERT WITH COOKIE = @cookie;
-- Verify the context switch reverted.
SELECT SUSER_NAME(), USER_NAME();
GO