СТАТЬЯ
16.01.02

Профессионалу разработчику. Безопасность без размножения баз данных: виртуальные частные базы данных Oracle (Часть 1)
 
© Стефан Линдблад, (Stefan Lindblad, Oracle Corporation)
Статья была опубликована в журнале OracleMagazine
 
 Данная публикация представляет собой дальнейшее развитие темы, рассмотренной в статье Т.Кайта “Детальный контроль доступа и контексты приложения”.
 
Аннотация  

Одна из проблем, с которыми мы сталкиваемся сегодня, – слежение за огромным количеством баз данных в наших системах. Метод создания одной базы данных для каждого экземпляра приложения ведет к локальному сопровождению данных и очень часто к ненужной сложности для администратора базы данных. Данный документ намерен показать пути уменьшения сложности за счет объединения нескольких баз данных в одну. Одна из проблем, которые могут появляться после такого объединения, – это дубликаты строк, которые могут появиться в таблицах, формируемых из различных источников. Отсюда возникают специальные требования, как к процессу миграции, так и, возможно даже, к переписыванию приложения. Здесь мы покажем, как можно объединить две или более баз данных в одну без изменения приложения. Это достигается с помощью виртуальных частных баз данных Oracle9i – Virtual Private Database (VPD). (Многие возможности виртуальных частных баз данных были реализованы в Oracle8i – Прим. перев.)

Виртуальная частная база данных

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

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

Для принудительной поддержки политик безопасности для объектов, с которыми эти политики связаны, детальное управление доступом полагается на “динамическую модификацию запросов”. Здесь под “запросом” понимаются не только операторы, которые начинаются с SELECT, а любая выборка из таблиц или представлений, включая доступ к данным операторами “QUERY-FOR-UPDATE”, INSERT или DELETE.

Доступ пользователя (непосредственный или косвенный) к таблице или представлению, которое имеет связанную с ним политику безопасности, заставляет сервер динамически модифицировать оператор, добавляя к нему условие “WHERE” (называемое также предикатом), которое возвращается функцией, поддерживающей политику безопасности. Оператор SQL модифицируется динамически, прозрачным для пользователя образом, с использованием любых условий, которые могут быть выражены в функции или возвращены ею.
 
Рассмотрим клерка отдела кадров, которому позволено видеть только записи служащих в самолетном подразделении (Aircraft Division). Когда пользователь выдает запрос "SELECT * FROM employees", функция, поддерживающая политику безопасности, возвращает предикат “division = ‘AIRCRAFT’”, и база данных прозрачным для пользователя образом перезаписывает запрос так, что фактически выполненным будет запрос:
SELECT * FROM employees WHERE division = ‘AIRCRAFT’;
Предикат, который мы хотим добавить, может быть не связанным точным соответствием со столбцом в той же самой таблице, из которой мы делаем выборку. Возможно, таблица служащих в предыдущем примере не содержит названий подразделений для каждого служащего. Вместо этого, они могли быть определены в таблице отделов. Это делало бы добавляемый предикат немного более сложным и фактически выполненный запрос будет примерно следующим:
SELECT * FROM employees where deptno
IN (Select deptno from employees where division = ‘AIRCRAFT’;
Итак, каждый раз при выполнении этого запроса таблицы служащих, мы будем иметь хорошую защиту, но не обязательно хорошую производительность. Так что важно, когда мы программируем предикаты для обеспечения безопасности, стремиться к снижению потребления системных ресурсов. Именно поэтому мы будем использовать контексты приложений.
 
Контекст приложения
 
Многие организации для управления доступом хотят принимать решения, основанные на каких-то знаниях о пользователях (таких, как роль пользователя в организации, его организационная единица, является ли он заказчиком или партнером) и о самом приложении (обращается ли пользователь к приложению главной бухгалтерской книги, как менеджер этого гроссбуха, или к приложению учета кадров, как служащий).
 
Защищенные контексты приложений расширяют возможности разработчиков для реализации в Oracle9i виртуальной частной базы данных. Несмотря на то, что использование этого средства не является обязательным, оно существенно упрощает реализацию детального контроля доступа и делает его более надежным. Контексты приложений имеют следующие достоинства:
Так, чтобы сделать предыдущий запрос более эффективным, мы установим полномочия пользователей во время их входа в базу данных. И затем эти полномочия могут использоваться в приложении без замедления его производительности.
 
Использование пакета DMBS_RLS
 
Встроенный пакет DBMS_RLS совместно с созданием контекста приложения обеспечивает безопасность приложения на уровне строк.
 
Можно поддерживать различные политики безопасности для различных типов SQL-операторов. Например, можно позволять пользователю извлекать все записи в таблице заказчиков, но разрешать обновление только тех строк, которые принадлежат ему. Определение политик безопасности в пакете, а затем назначение набора политик для таблицы, приводит к принудительному применению этих правил. Каждая политика динамически создает предикат, который будет присоединен к предложению WHERE любого оператора DML или SELECT, которые обращаются к этой таблице. Принудительная политика безопасности действует независимо от приложения, которое клиент использует для доступа к данным.
 
Приведем небольшой пример использования виртуальной частной базы данных с небольшим набором таблиц. В этом примере будут использованы две таблицы – CUSTOMER (заказчик) и INVOICE (счет). Цель состоит в том, чтобы каждый пользователь мог видеть только свои собственные строки. Таким образом, каждый пользователь может соединиться с базой данных и выдать один и тот же запрос, но будет видеть разные строки, в зависимости от того, кто он такой.
 
Для создания контекста приложения, который будет обеспечивать нашу прикладную систему информацией, связанную с безопасностью, выполним следующие шесть шагов:
  1. Проектирование политики безопасности.
  2. Создание контекста приложения.
  3. Создание пакета безопасности приложения, определяющего атрибуты контекста.
  4. Установка вызова пакета безопасности приложения для автоматического заполнения его атрибутов при входе пользователей в систему.
  5. Создание пакета политики безопасности для защиты таблиц. Функция политики безопасности в пакете позволит использовать атрибуты контекста приложения.
  6. Прикрепление политики безопасности к таблице.
 Проектирование политики безопасности
 
Для создания комплексного пакета политики безопасности, прежде всего, необходимо определить политику безопасности, которая будет принудительно поддерживаться. Для таблицы INVOICE после выполнения всех шагов будет поддерживаться следующая политика.
 
Владельцем таблиц приложения будет пользователь Scott. Только Scott будет иметь право выборки (SELECT) всех строк. Все другие смогут видеть только свои собственные данные.
 
Права SELECT будут определяться во время выполнения по столбцу CUSTOMER_ID (идентификатор заказчика) в таблице INVOICE. К этому нужно подготовиться во время входа пользователей в систему – каждый заказчик идентифицируется при входе в систему, этот идентификатор будет сохраняться в таблице CUSTOMER в столбце LOGIN_ID. Для гарантированного обеспечения недоступности таблицы CUSTOMER для пользователей, мы также прикрепим к ней политику безопасности.
 
Если в систему войдет кто-нибудь другой, то во всех таблицах он ничего не сможет увидеть.
 
Пример создания пакета политики безопасности запросов таблиц INVOICE и CUSTOMER будет приведен ниже. В этом пакете будут принудительно поддерживаться заданные нами правила запроса данных.
 
Создание контекста приложения
 
Теперь пришло время создать контекст приложения, и этот контекст будет использоваться в приложении для хранения информации о том, кто и когда соединяется с базой данных. Эта информация будет использоваться (через связанные переменные) в нашей политике безопасности, как только мы определим ее.
SQL> create context invoice_context
  2  using invoice_conpack;
Контекст создан.
 
Создание пакета безопасности приложения, определяющего атрибуты контекста
120
 
Пакет безопасности приложения будет заполнять атрибуты контекста приложения и позже будет сконфигурирован для выполнения во время входа пользователей в систему, автоматически устанавливая пользовательский контекст приложения. Для установки атрибутов в контексте используется встроенная процедура DBMS_SESSION.SET_CONTEXT.
120
SQL> create or replace package invoice_conpack
  2  is
  3   procedure set_custno;
  4  end;
  5  /
 Package created. 
SQL> create or replace package body invoice_conpack
  2  is
  3  procedure set_custno is
  4   v_custno varchar2(100);
  5  begin
  6   select customer_id into V_custno
  7   from scott.customer;
  8 
  9   dbms_session.set_context('invoice_context','custno',v_custno);
 10  exception
 11   when no_data_found then
 12    null
 13  end;
 14  end invoice_conpack;
 15  /

 Package body created.

Этот пакет делает простую выборку из таблицы CUSTOMER и устанавливает в новой переменной контекста CUSTNO значение переменной PL/SQL – V_CUSTNO. Если вошедший в базу данных пользователь не является заказчиком, ничего не будет установлено.
 
Установка вызова пакета безопасности приложения для автоматического заполнения его атрибутов при входе пользователей в систему.
 
Атрибуты контекста приложения можно устанавливать, вызывая процедуру их установки из приложения, но более предпочтительной может быть автоматическая установка атрибутов в самом начале, когда пользователь соединяется с базой данных. Для этого можно создать триггер событий, который срабатывает при соединении пользователей с базой данных. Этот триггер будет вызывать пакет, заполняющий атрибуты контекста. В данном примере триггер LOG_ON_SECURITY вызывает процедуру INVOICE_CONPACK.SET_CUSTNO, которая заполняет атрибуты пользовательского контекста приложения.
SQL> create or replace trigger scott.log_on_security
  2  after logon on database
  3  call scott.invoice_conpack.set_custno
  4  /
 
Trigger created.
Замечание: если после создания (или при попытке создания) этого триггера возникли проблемы соединения с базой данных, соединитесь как SYS AS SYSDBA и уничтожьте или отключите триггер.
 
Создание пакета политики безопасности для защиты таблиц
 
Функции политики безопасности в пакете будут использовать атрибуты контекста приложения.
SQL> create or replace package invoice_polpack
  2  is
  3  function custno(d1 varchar2, d2 varchar2) return varchar2;
  4  function log_id(d1 varchar2, d2 varchar2) return varchar2;
  5  end;
  6  /
 
Package created.
 
SQL> create or replace package body invoice_polpack is
  2  function custno (d1 varchar2, d2 varchar2) return varchar2 is
  3  d_predicate varchar2(2000);
  4 begin
  5      if user = 'SCOTT' then
  6          d_predicate := '1=1';
  7      else
  8          d_predicate := 'CUSTOMER_ID =
sys_context(''x_invoice_context'',''custno'')';
  9      end if;
 10
 11      return d_predicate;
 12  end custno;
 13  function log_id (d1 varchar2, d2 varchar2) return varchar2 is
 14   d_predicate varchar2(2000);
 15  begin
 16      if user = 'SCOTT' then
 17          d_predicate := '1=1';
 18      else
 19   d_predicate := 'LOGIN_ID = SYS_CONTEXT(''USERENV'',''session_user'')';
 20      end if;
 21      return d_predicate;
 22  end log_id;
 23  end invoice_polpack;
 24  /
 25 
 
Package body created.
Сейчас, создав пакет политики безопасности, мы создали два разных предиката. Один будет использоваться, когда пользователь является заказчиком. Другой будет использоваться, когда вошедший в систему пользователь – SCOTT. Естественно, пакет политики безопасности может быть расширен для более комплексной фильтрации пользователей и их рабочих ролей.
 
Назначение политики таблице
 
Сейчас нужно назначить наши политики правильной таблице, для этого пользователь SCOTT должен иметь право выполнения пакета DBMS_RLS.
 
SQL> begin
  2     dbms_rls.add_policy('scott',
  3                         'invoice ',
  4                         'invoice_policy',
  5                         'scott',
  6                         'invoice_polpack.custno',
  7                         'select');
  8 
  9     dbms_rls.add_policy('scott',
 10                         'customer',
 11                         'customer_policy',
 12                         'scott',
 13                         'invoice_polpack.log_id',
 14                         'select');
 15  end;
 16  /
 
PL/SQL procedure successfully completed.
Теперь мы готовы к тестированию приложения. Все что нам нужно – войти в систему как один из заказчиков и проверить, что он видит только свои собственные данные. Затем, войти в систему как SCOTT и проверить, что он видит все данные.
 
Вот что может увидеть заказчик Stefan:
SQL> select * from scott.customer;
 
CUSTOMER_ID NAME                           LOGIN_ID
----------- ------------------------------ ----------
          1 Stefan Lindblad                STEFAN
 
SQL> select * from scott.invoice;
 
    INV_ID     AMOUNT CUSTOMER_ID
---------- ---------- -----------
         1        500           1
         3        700           1
         6       1500           1
         8       3500           1
        13       8500           1
        15      10500           1
        19       5800           1
 
7 rows selected.
А это может увидеть владелец приложения Scott:
SQL> select * from scott.customer;
 
CUSTOMER_ID NAME            LOGIN_ID
----------- ------------------------------ ----------
          1 Stefan Lindblad              STEFAN
          2 Nils Nilsson                     NISSE
          3 Scott King                         SCOTT
          4 John Smith                       JOHN
 
SQL> select * from scott.invoice;
 
       INV_ID     AMOUNT CUSTOMER_ID
    ---------- ---------- -----------
         1        500           1
         2        600           2
         3        700           1
         4        800           4
         5        900           3
                 .
                 .
                 .
                 .
        20       5900           4
 
20 rows selected. 
Здесь можно видеть, что порядок размещения нами различных условий в функциях безопасности, позволяет пользователю SCOTT видеть все строки, даже притом, что есть заказчик по имени SCOTT.
 
В этой части было представлено краткое описание установки детального контроля доступа, использующего контекст и триггер входа в систему.
 
Виртуальная частная база данных в новых приложениях
 
Для того чтобы добавить эти функциональные возможности в недавно разработанное приложение или в приложение, для которого имеется возможность изменить его код, потребуется напряженная работа для определения, как политика должна работать. Как только это сделано, наиболее вероятно, что удобно будет иметь дополнительное поле для каждой строки, в котором можно хранить информацию о безопасности. Если выбран этот подход, то он очень близок к меткам безопасности Oracle.
 
Метки безопасности Oracle
 
Метки безопасности Oracle – технология виртуальных частных баз данных в Oracle9i стала фундаментом нового продукта Oracle, названного Oracle Label Security (OLS). Метки безопасности Oracle базируются на концепции маркирования, используемой в правительственных и военных организациях для защиты критической информации и обеспечения разделения данных. В этих сферах использования метки обычно состоят из иерархического уровня и одной или более категорий (или отделений). Метки безопасности Oracle можно использовать для модификации существующих приложений – реализация модели ASP (Active Server Pages – активные серверные страницы). Их также можно использовать в приложениях здравоохранения и CRM (Customer Relationship Management – управление взаимоотношениями с клиентами).
 
Oracle Label Security имеет следующие достоинства:

Часть 2 >>

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Обсудить на форуме Oracle
Отправить ссылку на страницу по e-mail


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован:16.01.02