Основные сведения о переключении контекста
Контекст выполнения определяется подключенным к сеансу пользователем или именем входа или же выполняющимся (вызывающим) модулем. Он устанавливает идентификатор пользователя или имени входа, чьи разрешения на выполнение инструкций или совершение действий проверяются. В SQL Server контекст выполнения может переключаться на другого пользователя или имя входа при помощи выполнения инструкции EXECUTE AS или определения предложения EXECUTE AS в модуле. После переключения контекста SQL Server проверяет разрешения у имени входа и пользователя этой учетной записи, а не у того, кто вызвал инструкцию EXECUTE AS, или модуля. Пользователь или учетная запись входа олицетворяется на оставшееся время выполнения модуля или сеанса либо до того момента, когда происходит явное восстановление переключения контекста. Дополнительные сведения о контексте выполнения см. в разделе Основные сведения о контексте выполнения.
Явное переключение контекста
Контекст выполнения сеанса или модуля может быть явно изменен при помощи определения пользователя или имени входа в инструкции EXECUTE AS. Олицетворение остается в силе до тех пор, пока не произойдет одно из следующих событий:
Сеанс удаляется.
Контекст переключен на другое имя входа или на другого пользователя.
Контекст восстановлен до контекста предыдущего выполнения.
Использование EXECUTE AS для явного олицетворения другого пользователя подобно использованию инструкции SETUSER в предыдущих версиях SQL Server. Дополнительные сведения см. в разделе EXECUTE AS и SETUSER: сравнение.
Явное переключение контекста на уровне сервера
Для переключения контекста выполнения на уровне сервера используйте инструкцию EXECUTE AS LOGIN = 'login_name'. Имя входа должно быть видимым как участник в sys.server_principals, а тот, кто вызывает инструкцию, должен иметь разрешение IMPERSONATE для заданного имени входа.
Когда контекст выполнения находится на уровне сервера, область олицетворения будет следующей:
Подлинность маркера имени входа для login_name проверена экземпляром SQL Server и действительна на этом экземпляре.
Соблюдаются разрешения уровня сервера и принадлежность login_name к ролям.
Для возврата к предыдущему контексту используется инструкция REVERT. Вызывающий инструкцию REVERT должен находиться в базе данных, где произошло олицетворение.
Пример
В следующем примере Питер Коннели, сетевой администратор компании Adventure Works Cycles, хочет создать учетную запись имени входа SQL Server для нового сотрудника Цзинхао Люхаса. У имени входа Питера в SQL Server нет необходимых для создания имен входа SQL Server разрешений уровня сервера, но Питер обладает разрешением IMPERSONATE в adventure-works\dan1, имени входа SQL Server с нужным разрешением уровня сервера. Когда Питер подключается к экземпляру SQL Server, контекст выполнения сеанса образуется из его имени входа в SQL Server. Чтобы создать имя входа SQL Server, Питер временно принимает контекст выполнения adventure-works\dan1. Затем он создает имя входа. Наконец, он освобождает присвоенные разрешения.
-- Switch execution context to the adventure-works\dan1 login account.
EXECUTE AS LOGIN = 'adventure-works\dan1';
-- Create the new login account.
CREATE LOGIN Jinghao1 WITH PASSWORD = '3KHJ6dhx(0xVYsdf';
-- Revert to the previous execution context.
REVERT;
Явное переключение контекста на уровне баз данных
Для переключения контекста выполнения на уровне базы данных используйте инструкцию EXECUTE AS USER = 'user_name'. Имя пользователя должно значиться в качестве участника в представлении sys.database_principals, а тот, кто вызывает инструкцию, должен иметь разрешения IMPERSONATE на это имя пользователя.
Когда контекст выполнения находится на уровне базы данных, область олицетворения будет следующей:
Подлинность маркера имени пользователя для user_name проверена экземпляром SQL Server и действительна для текущей базы данных. Дополнительные сведения о расширении олицетворения пользователя вне области текущей базы данных см. в разделе Расширение олицетворения базы данных с помощью инструкции EXECUTE AS.
Соблюдаются разрешения уровня базы данных и принадлежность user_name к ролям текущей базы данных. Разрешения уровня серверов, выданные явно для идентификатора маркера пользователя или наследуемые от роли, не соблюдаются.
Для возврата к предыдущему контексту используется инструкция REVERT. Вызывающий инструкцию REVERT должен находиться в базе данных, где произошло олицетворение.
Пример
В следующем примере, Франсуа Аженста, администратор базы данных компании Adventure Works Cycles, хочет выполнить инструкцию DBCC CHECKDB в базе данных AdventureWorksDW, но не имеет для этого разрешений на уровне базы данных. Однако он обладает разрешениями IMPERSONATE пользователя dan1, учетной записи с нужным разрешением.
Когда Франсуа подключается к базе данных AdventureWorksDW, контекст выполнения сопоставляется с его маркером безопасности пользователя. Разрешения на выполнение инструкций проверяются у первичных и вторичных участников в его маркере пользователя. Из-за того, что он не обладает разрешениями, необходимыми для выполнения инструкции DBCC CHECKDB, он выполняет следующие инструкции.
-- EXECUTE AS USER = 'dan1';
-- Create a table in dan1's default schema
CREATE TABLE t_NewTable( data nvarchar(100) );
go
-- Revert to the previous execution context.
REVERT
go;
Неявное переключение контекста
Контекст выполнения модуля, такого как хранимая процедура, триггер, очередь или пользовательская функция, может быть явно изменен при помощи определения пользователя или имени входа в инструкции EXECUTE AS при определении модуля.
Определяя контекст, в котором выполняется модуль, можно управлять тем, какая пользовательская учетная запись SQL Server используется для проверки разрешений модуля на осуществления ссылки на любые объекты базы данных. Это обеспечивает дополнительную гибкость и контроль в управлении разрешениями внутри цепочки объекта, которая существует между модулями, определяемыми пользователем и объектами, содержащими ссылки этих модулей. Тогда пользователям необходимо будет предоставлять разрешения на сам модуль, без выдачи явных разрешений на объекты, на которые он ссылается. Только пользователь, модуль которого выполняет олицетворение, должен обладать разрешениями на объекты, с которыми работает модуль.
Уровень олицетворения определяется типом модуля, в котором задано олицетворение.
Олицетворение на уровне сервера может быть задано в следующих объектах:
- Триггеры DDL.
Область олицетворения на уровне сервера такая же, как определено ранее в пункте «Явное переключение контекста на уровне баз данных».
Олицетворение на уровне баз данных может быть задано в следующих объектах:
Триггеры DML.
Очереди.
Хранимые процедуры.
Пользовательские функции.
Область олицетворения на уровне сервера такая же, как определено ранее в пункте «Явное переключение контекста на уровне баз данных».
Дополнительные сведения о неявном переключении контекста см. в разделе Использование инструкции EXECUTE AS в модулях.
Пример
В следующем примере Мэри является владельцем таблицы MyTable. Она хочет, чтобы пользователь Скотт имел возможность усекать таблицы, но у Скотта нет прямого разрешения на работу с таблицами. Поэтому она создает хранимую процедуру dbo.usp_TruncateMyTable и предоставляет Скотту разрешение EXECUTE для этой процедуры. Когда Скотт выполняет эту хранимую процедуру, компонент Database Engine проверяет разрешения на усечение таблицы, как если бы хранимую процедуру выполняла Мэри. Так как она является владельцем таблицы, то инструкция выполнится даже в том случае, если Скотт не обладает прямыми разрешениями на работу с таблицами.
CREATE PROCEDURE dbo.usp_TruncateMyTable
WITH EXECUTE AS SELF
AS TRUNCATE TABLE MyDB..MyTable;
См. также