Введение в проблему В настоящее время в любой организации действует ограничение доступа к информации на основании определенных знаний о пользователе.
Такими знаниями могут быть роль пользователя в организации, его должность или структурное подразделение, в котором работает пользователь.
Многие знают, что проблему ограничения доступа можно решить с помощью простых механизмов, основанных на имени пользователя, таблицах, представлениях и триггерах.
Давайте посмотрим на пример: Предоставить менеджеру информацию о клиентах организации.
При этом руководитель может видеть клиентов только своего структурного подразделения, а не всей компании:
Простое решение — создать отдельное представление для каждого отдела компании.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;
Для пользователя MGR_10: select user from dual;
select * from clients;
Для пользователя MGR_20: select user from dual;
select * from clients;
Для пользователя MGR_10_20_30: select user from dual;
select * from clients;
Информация о представлениях в базе данных хранится в представлениях user_policies, all_policies, dba_policies. Выполним запрос от имени пользователя с правами DBA: select * from dba_policies;
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;
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;
Begin
DBMS_RLS.ENABLE_POLICY (
object_schema => 'myuser',
object_name => 'clients',
policy_name => 'clients_policy',
enable => false
);
End;
select * from dba_policies;
Begin
DBMS_RLS.ENABLE_POLICY (
object_schema => 'myuser',
object_name => 'clients',
policy_name => 'clients_policy'
);
End;
select * from dba_policies;
Самые внимательные, думаю, заметили параметр 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
-
Автоматические Рекурсивные Вычисления
19 Oct, 24 -
Знакомство С Qt Для Raspberry Pi 3
19 Oct, 24 -
Чего Вы Ждете От Суперхабра?
19 Oct, 24 -
Forkcms — Новая Вилка С Ложкой
19 Oct, 24 -
Цензура Уже Существует В Рунете
19 Oct, 24 -
Тролли Против Google. Часть Вторая.
19 Oct, 24