Блокировка доступа к данным в SQL Server

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

Безопасность на уровне строк (Row-Level Security, RLS) ограничивает пользователей таким образом, чтобы они могли работать исключительно с теми данными, к которым у них имеется доступ. Кроме того, данная функция не дает возможности пользователям вставлять, обновлять или удалять данные, доступ к которым запрещен.

Давайте рассмотрим, как можно использовать функцию Row-Level Security на примере условной таблицы, назовем ее ObjectCheck, в которой отражена информация об объектах аудита, сроках начала и завершения проверок и т.д.

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

Для выполнения примера создадим трех пользователей базы данных:

create user Ivanovii without login; create user PetrovPP without login; create user SidorovSS without login;

предоставим доступ select к таблице ObjectCheck для этих пользователей:

grant select on ObjectCheck to Ivanovii; grant select on ObjectCheck to PetrovPP; grant select on ObjectCheck to SidorovSS;

Кроме того, желательно создать отдельную схему для объектов базы данных Row-Level Security:

create schema rs; GO

Ограничение доступа к данным с использованием Row-Level Security достигается путем определения предиката безопасности (Security predicate) как функции, которая ограничивает строки на основе логики фильтрации, которая вызывается и применяется политикой безопасности (Security Policy), созданной с помощью T-SQL оператора create security policy, и работает как контейнер предикатов.

Давайте выполним настройку функции безопасности на уровне строк для таблицы ObjectCheck.

Создаем функцию, зависящую от пользователей, вошедших в систему, чтобы была возможность фильтровать пользователей и проверять их доступы к данным:

create function rs.fn_secureData(@Username as sysname) returns table with schemabinding as return select 1 as 'secureObjectCheck' where @Username = User_Name();

Создадим политику безопасности в таблице ObjectCheck, используя ранее созданную функцию предиката:

create security policy Object_Check add filter predicate rs.fn_secureData(User) on dbo.ObjectCheck with (state = on);

Теперь защита на уровне строк настроена и готова к фильтрации доступа к данным в таблице ObjectCheck.

Так, если выполнить запрос, указав пользователя Ivanovii:

execute as user = 'Ivanovii'; select * from ObjectCheck; revert;

то запрос вернет только две записи, связанные с пользователем Ivanovii:

Аналогичный результат будет возвращен при запросе данных из таблицы ObjectCheck пользователями PetrovPP и SidorovSS:

execute as user = 'PetrovPP'; select * from ObjectCheck; revert;
execute as user = 'SidorovSS'; select * from ObjectCheck; revert;

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

Если необходимо прекратить использование функции безопасности rs.fn_SecureData, то можно отключить политику безопасности Object_Check с помощью инструкции ALTER security policy:

alter security policy Object_Check with (state = off)

Затем выполнить запрос DROP для удаления функции и политики безопасности:

drop security policy Object_Check drop function rs.fn_secureData

Теперь безопасность на уровне строк полностью удалена из таблицы Object_Check.

Можно легко добавлять предикаты и критерии фильтрации, подходящие для определенных ситуаций, однако, слишком сложные предикаты ухудшают производительность базы данных, поскольку предикат будет проверяться каждый раз при выполнении доступа к данным. Более подробно ознакомиться с Row-Level Security можно на сайте Microsoft.

0
Комментарии
-3 комментариев
Раскрывать всегда