Есть разные способы показать пользователю только те данные, которые ему нужны. Row level security — один из самых универсальных, простых и надежных. Прочитав эту статью, ты поймешь, что это несложно, и научишься организовывать разграничение доступа к записям средствами самой БД без особого ущерба для производительности.
Механизм row level security позволяет реализовать разграничение доступа к данным средствами базы данных прозрачно для работающих с ней приложений. Даже если злоумышленник получил прямой доступ к базе, например под учетной записью владельца схемы с данными, RLS может не дать ему увидеть защищенную информацию. Политики RLS позволяют убирать строки из выборки целиком или скрывать значения столбцов для строк, к которым пользователь не имеет доступа. В этом отличие от обычного управления правами в БД, которые можно выдать только на объект целиком.
Как это работает? При выполнении любого запроса к базе планировщик проверяет, есть ли для этих таблиц политики доступа. Если есть, он вычисляет на основе каждой политики дополнительный предикат, который добавляет к запросу. Предикаты могут быть любой сложности. Например, вот такими:
and (512 in (select id_user from v_admin_users where id_department = 255) or 512 in (select id_user from v_bypass_rls))
Плюс в том, что предикаты работают для любых запросов, в том числе сделанных через инструменты администрирования (SQL Developer, Toad, PgAdmin и так далее) и даже при экспорте дампов. Это единый механизм управления доступом для всех приложений на уровне ядра СУБД. Почему он не так часто используется на практике? Вот несколько причин.
В общем, row level security — это инструмент для централизованного управления доступом к данным. Он реализован во многих современных СУБД — например, Oracle, PostgreSQL и MS SQL Server. В этой статье я покажу, как это работает в первых двух.
Начнем с реализации RLS в Oracle и сразу нырнем в практику.
Мы попробуем реализовать простую политику на стандартной схеме HR. Обычный пользователь может видеть только свои данные. Руководитель департамента может видеть все данные по департаменту. Для этого нам понадобится:
Мы будем считать, что приложение подключается к базе под учетной записью пользователя HR и в этой программе есть инструмент аутентификации, который позволяет понять, какой именно из сотрудников с ней работает. Данные о том, какой сотрудник подключен, мы будем сохранять в контексте — специальном key-value хранилище атрибутов, управляющих приложениями. Можно использовать стандартный CLIENT_IDENTIFIER
, но мы создадим свой собственный. Для этого придется создать и пакет, который будет с ним работать.
Для начала создадим от имени привилегированного пользователя контекст и сразу укажем, какой пакет может его менять:
CREATE CONTEXT SECURITY_CONTEXT USING HR.P_SEC_CONTEXT;
Создаем пакет для работы с контекстом:
create or replace package P_SEC_CONTEXT is procedure set_employee(p_employee_id in number); end P_SEC_CONTEXT; / create or replace package body P_SEC_CONTEXT is procedure set_employee(p_employee_id in number) is begin dbms_session.set_context(namespace => 'SECURITY_CONTEXT', attribute => 'EMPLOYEE_ID', value => p_employee_id); end; end P_SEC_CONTEXT; /
Теперь p_sec_context.set_employee
будет использоваться приложением, чтобы задать код сотрудника в таблице EMPLOYEES
, который работает в этой сессии БД.
При использовании пула соединений нужно задавать контекст каждый раз при получении нового подключения. Значение по умолчанию можно задавать в триггере на логин, но это не обязательно. Пример триггера:
create trigger tr_hr_logon after logon on HR.SCHEMA begin p_sec_context.set_employee(null); end; /
При использовании CLIENT_IDENTIFIER
вместо p_sec_context.set_employee
нужно указать dbms_session.set_identifier
.
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
1 год7690 р. |
1 месяц720 р. |
Я уже участник «Xakep.ru»
Читайте также
Последние новости