В SQL Server оператор “Execute as” позволяет явно или неявно определить контекст выполнения сеанса. Эта функция особенно полезна для администраторов баз данных при проверке разрешений конкретного пользователя или когда пользователь хочет выполнить хранимую процедуру в контексте другого пользователя.
Рассмотрим сценарий, в котором администратор баз данных, мистер Смит, получил запрос на создание логина SQL Server для пользователя по имени Шираиши и предоставление доступа к его учетной записи Windows. Кроме того, мистер Смит должен предоставить только чтение для таблицы с именем “products” в схеме “CompanyProducts”, но ограничить доступ к таблице “productprice” в той же схеме.
Для демонстрации использования оператора “Execute as” предположим, что у нас есть база данных с именем “CompanyProducts” со следующей схемой и таблицами:
USE [master]
GO
IF EXISTS (SELECT name FROM sys.databases WHERE name = N'CompanyProducts')
DROP DATABASE [CompanyProducts]
GO
CREATE DATABASE CompanyProducts
GO
USE [CompanyProducts]
GO
IF EXISTS (SELECT * FROM sys.schemas WHERE name = N'CompanyCustomers')
DROP SCHEMA [CompanyCustomers]
GO
CREATE SCHEMA CompanyProducts
GO
USE [CompanyProducts]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[CompanyProducts].[Products]') AND type in (N'U'))
DROP TABLE [CompanyProducts].[Products]
GO
CREATE TABLE CompanyProducts.Products (id int, Name varchar(100))
GO
INSERT INTO CompanyProducts.Products VALUES (1, 'Холодильник')
INSERT INTO CompanyProducts.Products VALUES (2, 'Стиральная машина')
INSERT INTO CompanyProducts.Products VALUES (3, 'Сушилка')
INSERT INTO CompanyProducts.Products VALUES (4, 'Газонокосилка')
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[CompanyProducts].[ProductPrice]') AND type in (N'U'))
DROP TABLE [CompanyProducts].[ProductPrice]
GO
CREATE TABLE CompanyProducts.ProductPrice (id int, Price money)
GO
INSERT INTO CompanyProducts.ProductPrice VALUES (1, 7000)
INSERT INTO CompanyProducts.ProductPrice VALUES (2, 1000)
INSERT INTO CompanyProducts.ProductPrice VALUES (3, 1000)
INSERT INTO CompanyProducts.ProductPrice VALUES (4, 2500)
GO
Теперь мистер Смит может приступить к созданию необходимого логина и пользователя для мисс Шираиши:
USE master
GO
CREATE LOGIN Shiraishi WITH PASSWORD = 'Sh!r@!sh!'
GO
CREATE LOGIN [SQL2005Shiraishi] FROM WINDOWS
GO
USE CompanyProducts
GO
CREATE USER SQL_Shiraishi FOR LOGIN Shiraishi
GO
CREATE USER WIN_Shiraishi FOR LOGIN [SQL2005Shiraishi]
GO
GRANT SELECT ON CompanyProducts.Products TO SQL_Shiraishi, WIN_Shiraishi
GO
DENY SELECT ON CompanyProducts.ProductPrice TO SQL_Shiraishi, WIN_Shiraishi
GO
Теперь мистер Смит хочет проверить разрешения как для SQL-логина, так и для Windows-логина мисс Шираиши. Поскольку он знает пароль для SQL-логина, он может легко проверить разрешения с помощью утилиты SQLCMD или Management Studio. Однако у него нет пароля для Windows-логина, что затрудняет проверку разрешений.
К счастью, SQL Server 2005 представил оператор “EXECUTE AS”, который позволяет мистеру Смиту проверить разрешения обоих логинов без необходимости знать пароль. Он может выполнить следующие команды:
USE CompanyProducts
GO
EXECUTE AS USER = 'SQL_Shiraishi'
SELECT * FROM CompanyProducts.Products -- РЕЗУЛЬТАТ: 1 Холодильник, 2 Стиральная машина, 3 Сушилка, 4 Газонокосилка
SELECT * FROM CompanyProducts.ProductPrice -- РЕЗУЛЬТАТ: Msg 229, Level 14, State 5, Line 1 SELECT permission denied on object 'ProductPrice', database 'CompanyProducts', schema 'CompanyProducts'
GO
Используя оператор “EXECUTE AS USER”, мистер Смит может переключить контекст выполнения на SQL-логин мисс Шираиши и проверить разрешения. Как и ожидалось, у нее есть доступ к таблице “products”, но доступ к таблице “productprice” запрещен.
Аналогично мистер Смит может открыть новое окно запроса с собственными учетными данными и выполнить следующие команды для проверки разрешений Windows-логина:
EXECUTE AS USER = 'WIN_Shiraishi'
SELECT * FROM CompanyProducts.Products -- РЕЗУЛЬТАТ: 1 Холодильник, 2 Стиральная машина, 3 Сушилка, 4 Газонокосилка
SELECT * FROM CompanyProducts.ProductPrice -- РЕЗУЛЬТАТ: Msg 229, Level 14, State 5, Line 1 SELECT permission denied on object 'ProductPrice', database 'CompanyProducts', schema 'CompanyProducts'
GO
Оператор “EXECUTE AS USER” позволяет мистеру Смиту переключить контекст выполнения на Windows-логин мисс Шираиши и проверить разрешения. Результаты такие же, как и раньше, с доступом к таблице “products” и запретом доступа к таблице “productprice”.
В заключение, оператор “Execute as” в SQL Server является мощным инструментом для администраторов баз данных для проверки разрешений конкретных пользователей. Он позволяет легко переключать контексты выполнения и предоставляет удобный способ проверить права доступа без необходимости знать пароль пользователя. Эта функция особенно полезна в ситуациях, когда проверка разрешений необходима, но получение паролей или просьба пользователей войти с использованием своих учетных данных не является возможным или рекомендуется.