Оракул. Безопасность На Уровне Строк



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

Такими знаниями могут быть роль пользователя в организации, его должность или структурное подразделение, в котором работает пользователь.

Многие знают, что проблему ограничения доступа можно решить с помощью простых механизмов, основанных на имени пользователя, таблицах, представлениях и триггерах.

Давайте посмотрим на пример: Предоставить менеджеру информацию о клиентах организации.

При этом руководитель может видеть клиентов только своего структурного подразделения, а не всей компании:

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

create table clients ( clientid integer, clientname varchar2(30), clientphone varchar2(7), clientoffice integer );

Простое решение — создать отдельное представление для каждого отдела компании.

Например:

create or replace view clients_10 as select clientid, clientname, clientphone from clients where clientoffice = 10;

Таким образом, нам придется поддерживать количество просмотров равным * , а также «направить» каждого пользователя к необходимым данным.

Глупая и скучная задача.

Попробуем улучшить предыдущий пример:

create or replace view v_clients as select clientid, clientname, clietnphone from office where clientoffice = (select useroffice from users where username = user);

Решение, несомненно, интереснее, но что делать, когда одному пользователю нужно «видеть» клиентов нескольких отделов? Также часто возникает ситуация, когда одному пользователю разрешено запрашивать данные только из одной таблицы, в другой он может редактировать, но не удалять, а в третьей — просматривать и удалять.

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



технология РЛС

Технология РЛС ( безопасность на уровне строк или безопасность на уровне строк) предоставляет возможность создавать политики безопасности, ограничивающие доступ пользователей к информации в базе данных.

Как уже говорилось выше, политики безопасности позволяют либо «закрыть» информацию полностью или частично, либо разрешить только определенные операции с ней.

Впервые технология была представлена в Oracle 8i, однако в последующих версиях ее возможности были существенно расширены.

При подключении объекта базы данных к политике безопасности управление доступом осуществляется посредством логики, записанной в специальную PL/SQL-функцию.

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

Когда пользователь прямо или косвенно обращается к объекту базы данных (таблице, представлению), сервер динамически изменяет оператор SQL, добавляя к нему предикат WHERE, который возвращается функцией безопасности.



Функция безопасности

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

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



create or replace function policy_func (p_schema varchar2, p_object varchar2) return varchar2 is begin if (user = 'MGR_10_20_30 ') then return 'clientoffice in (10, 20, 30)'; elseif return 'clientoffice = (select useroffice from users where username = user)'; end if; end;

Приведенная выше функция добавит в SQL-запрос пользователя предикат WHERE clientoffice = office_no, где office_no — это номер отдела, в котором работает пользователь.

Для пользователя с логином MGR_10_20_30 будет добавлен предикат WHERE clientoffice в (10, 20, 30).

Таким образом, этому пользователю будет доступна информация о клиентах трех подразделений.



Процедуры пакета DBMS_RLS



Добавить_политику
Что ж, на этом этапе мы выполнили всю необходимую подготовительную работу, и нам осталось только добавить политику безопасности в нашу базу данных.

Политика безопасности регистрируется процедурой пакета DBMS_RLS add_policy:

DBMS_RLS.ADD_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2, function_schema IN VARCHAR2 NULL, policy_function IN VARCHAR2, statement_types IN VARCHAR2 NULL, update_check IN BOOLEAN FALSE, enable IN BOOLEAN TRUE, static_policy IN BOOLEAN FALSE, policy_type IN BINARY_INTEGER NULL, long_predicate IN BOOLEAN FALSE, sec_relevant_cols IN VARCHAR2 NULL, sec_relevant_cols_opt IN BINARY_INTEGER NULL );

Добавим политику безопасности для таблицы клиентов:

Begin DBMS_RLS.ADD_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy', function_schema => 'myuser', policy_function => 'policy_func', statement_types => 'select, insert, update, delete', update_check => true ); End;

Теперь кратко о параметрах процедуры, которые мы использовали: схема_объекта и имя_объекта – таблица, представление или синоним, для которого добавляется политика, и схема базы данных, в которой расположен объект. имя_политики – имя добавляемой политики безопасности.

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

function_schema и policy_function – имя функции безопасности, генерирующей предикат, и схема базы данных, в которой расположена эта функция.

типы_выражений – операторы, к которым применяется политика безопасности.

проверка обновления – опция запрещает операции INSERT или UPDATE, если INSERT или UPDATE нарушают условия поиска, указанные в предикате.

Теперь мы можем увидеть политику безопасности в действии:

select username, useroffice from users;



Оракул.
</p><p>
 Безопасность на уровне строк

Для пользователя MGR_10:

select user from dual;



Оракул.
</p><p>
 Безопасность на уровне строк



select * from clients;



Оракул.
</p><p>
 Безопасность на уровне строк

Для пользователя MGR_20:

select user from dual;



Оракул.
</p><p>
 Безопасность на уровне строк



select * from clients;



Оракул.
</p><p>
 Безопасность на уровне строк

Для пользователя MGR_10_20_30:

select user from dual;



Оракул.
</p><p>
 Безопасность на уровне строк



select * from clients;



Оракул.
</p><p>
 Безопасность на уровне строк

Информация о представлениях в базе данных хранится в представлениях user_policies, all_policies, dba_policies. Выполним запрос от имени пользователя с правами DBA:

select * from dba_policies;



Оракул.
</p><p>
 Безопасность на уровне строк



Drop_policy
Соответственно, поскольку существует процедура создания политики безопасности, есть и процедура ее удаления:

DBMS_RLS.DROP_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2 );

Попробуем удалить нашу политику безопасности:

Begin DBMS_RLS.DROP_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy' ); End;

Теперь проверим наличие политик в базе пользователем с правами DBA:

select * from dba_policies;



Оракул.
</p><p>
 Безопасность на уровне строк



Enable_policy
Помимо добавления/удаления политик безопасности, можно временно приостановить действие существующих политик.

Для этого используйте процедуру Enable_policy, которая делает политику неактивной (enable => false) или возобновляет политику (enable => true):

DBMS_RLS.ENABLE_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2, enable IN BOOLEAN TRUE) );



select * from dba_policies;



Оракул.
</p><p>
 Безопасность на уровне строк



Begin DBMS_RLS.ENABLE_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy', enable => false ); End;



select * from dba_policies;



Оракул.
</p><p>
 Безопасность на уровне строк



Begin DBMS_RLS.ENABLE_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy' ); End;



select * from dba_policies;



Оракул.
</p><p>
 Безопасность на уровне строк

Самые внимательные, думаю, заметили параметр Enable процедуры add_policy пакета dbms_rls. Этот параметр определяет, будет ли политика активной или неактивной сразу после создания.

Значение по умолчанию — правда.



Обновить_политику
Эта процедура позволяет обновить предикат политики RLS. Если политика безопасности определена с типом, отличным от DYNAMIC, предикат политики может не обновляться в течение некоторого времени, поскольку он кэшируется в памяти.

Поэтому, если есть необходимость немедленно обновить политику, то нужно выполнить процедуру REFRESH_POLICY, которая повторно выполнит функцию политики и обновит предикат в кеше.



DBMS_RLS.REFRESH_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2 NULL, policy_name IN VARCHAR2 NULL );



Заключение

В данной статье рассмотрен простейший пример, что называется, «на пальцах».

В следующей статье мы рассмотрим безопасность с использованием контекстов и групп политик.

Будьте в безопасности! Совершить! Теги: #oracle #dbms_rls #oracle

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.