Блокировка доступа к данным в SQL Server
Иногда возникает необходимость ограничения доступа ряду сотрудников к определенной информации, хранящейся в базе банных. Я предлагаю познакомиться с одной из функций SQL Server, которая позволяет контролировать доступ к уровню строк в таблице базы данных в зависимости от пользователя, выполняющего запрос.
Безопасность на уровне строк (Row-Level Security, RLS) ограничивает пользователей таким образом, чтобы они могли работать исключительно с теми данными, к которым у них имеется доступ. Кроме того, данная функция не дает возможности пользователям вставлять, обновлять или удалять данные, доступ к которым запрещен.
Давайте рассмотрим, как можно использовать функцию Row-Level Security на примере условной таблицы, назовем ее ObjectCheck, в которой отражена информация об объектах аудита, сроках начала и завершения проверок и т.д.
Перед нами поставлена задача: каждый пользователь базы данных должен получить доступ к данным, относящимся только к нему, без доступа к проверкам, назначенным другим сотрудникам.
Для выполнения примера создадим трех пользователей базы данных:
предоставим доступ select к таблице ObjectCheck для этих пользователей:
Кроме того, желательно создать отдельную схему для объектов базы данных Row-Level Security:
Ограничение доступа к данным с использованием Row-Level Security достигается путем определения предиката безопасности (Security predicate) как функции, которая ограничивает строки на основе логики фильтрации, которая вызывается и применяется политикой безопасности (Security Policy), созданной с помощью T-SQL оператора create security policy, и работает как контейнер предикатов.
Давайте выполним настройку функции безопасности на уровне строк для таблицы ObjectCheck.
Создаем функцию, зависящую от пользователей, вошедших в систему, чтобы была возможность фильтровать пользователей и проверять их доступы к данным:
Создадим политику безопасности в таблице ObjectCheck, используя ранее созданную функцию предиката:
Теперь защита на уровне строк настроена и готова к фильтрации доступа к данным в таблице ObjectCheck.
Так, если выполнить запрос, указав пользователя Ivanovii:
то запрос вернет только две записи, связанные с пользователем Ivanovii:
Аналогичный результат будет возвращен при запросе данных из таблицы ObjectCheck пользователями PetrovPP и SidorovSS:
Из приведенных примеров видно, что функция безопасности на уровне строк может использоваться для фильтрации данных, которые может видеть каждый пользователь, в зависимости от критериев фильтрации, определенных в функции предиката.
Если необходимо прекратить использование функции безопасности rs.fn_SecureData, то можно отключить политику безопасности Object_Check с помощью инструкции ALTER security policy:
Затем выполнить запрос DROP для удаления функции и политики безопасности:
Теперь безопасность на уровне строк полностью удалена из таблицы Object_Check.
Можно легко добавлять предикаты и критерии фильтрации, подходящие для определенных ситуаций, однако, слишком сложные предикаты ухудшают производительность базы данных, поскольку предикат будет проверяться каждый раз при выполнении доступа к данным. Более подробно ознакомиться с Row-Level Security можно на сайте Microsoft.