20 ноября 2023

MS SQL Server. Работа с данными от имени другого пользователя

    Я уже писал об использовании EXECUTE AS в MS SQL Server. Тогда я использовал "WITH EXECUTE AS OWNER" для изменения контекста безопасности на владельца триггера и "EXECUTE AS CALLER" для изменения контекста безопасности в коде триггера на пользователя, вызвавшего модуль. Хочу поговорить о вызове "EXECUTE AS" с указанием имени пользователя.

    Воспользуемся базами данных из предыдущей статьи. Нам понадобятся база данных db1 с пользователем user1 и база данных db2 с таблицей tdb2. Напомню, что пользователь user1 "не умеет" подключаться к базе данных db2 и тем более писать в таблицу tdb2. Поэтому его попытка после подключения к базе данных db1 добавить строку в таблицу tdb2 приведет к ошибке:

MS SQL Server EXECUTE AS: Ошибка 916 - The server principal is not able to access the database under the current security context
Попробуем переключить контекст безопасности выполнения кода на пользователя sa, который без проблем может добавить эту строку
MS SQL Server EXECUTE AS: Ошибка 15406 - Cannot execute as the server principal because the principal sa does not exist, this type of principal cannot be impersonated, or you do not have permission
и получим ошибку номер 15406 "Не удалось выполнить в качестве сервера-субъекта, так как субъект sa не существует, этот тип субъекта не может проходить олицетворение или отсутствует разрешение" ("Cannot execute as the server principal because the principal sa does not exist, this type of principal cannot be impersonated, or you do not have permission"). Мы точно знаем, что пользователь sa существует, поэтому логично предположить, что пользователю user1 не хватает прав прикрыться именем администратора для своих "темных делишек".

    Что бы пользователь мог переключать контекст безопасности выполнения кода на другого пользователя необходимо выдать ему разрешение на олицетворение его в качестве другого пользователя. У MS SQL Server это разрешение называется "IMPERSONATE" ("выдавать себя за"). Олицетворение может быть в качестве пользователя базы данных (ON USER) или в качестве логина СУБД (ON LOGIN).

    Администратором подключимся к базе данных master и выдадим разрешение пользователю user1 олицетворять себя как sa:

USE master
GO
GRANT IMPERSONATE ON LOGIN::sa TO user1
GO
Проверить наличие разрешения IMPERSONATE у user1 можно используя SQL Server Management Studio.
MS SQL Server Login properties - IMPERSONATE
В свойствах логина его можно не только посмотреть, но и добавить или удалить.

    Теперь пользователь user1 может переключить контекст безопасности выполнения кода на пользователя sa и добавить строку в таблицу:

EXECUTE AS LOGIN = 'sa'
INSERT INTO db2.dbo.tdb2 (id, name, is_active) VALUES (666, 'added by user1', 0)
REVERT
GO
Проверим наличие новой строки в таблице tdb2 выполнив запрос к ней пользователем user1, который к этой таблице не имеет доступа:
MS SQL Server EXECUTE AS: Результаты
Обратите внимание, что в скрипте после INSERT вызвана команда REVERT переключающая контекст выполнения кода на контекст, который был перед последним вызовом команды EXECUTE AS. В скрипте с SELECT команды REVERT нет, поэтому все остальные действия в этой сессии пользователь user1 будет выполнять от имени sa.

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

Комментариев нет:

Отправить комментарий