СТАТЬЯ
11.01.02

Детальный контроль доступа и контексты приложения (Часть 1)

© Том Кайт
Статья была опубликована в журнале OracleMagazine

Введение

В этой статье рассмотрены два новых механизма Oracle8i: детальный контроль доступа (Fine Grained Access Control) и контексты защищенных приложений (Secure Application Contexts). При совместном использовании они обеспечивают новые качественные возможности для обеспечения информационной безопасности базы данных.

Как и в других статьях этого цикла, в этом опусе будут рассмотрены:

В различных изданиях детальный контроль доступа может быть назван по-разному. Ниже перечислены его синонимы:

В двух словах, детальный контроль доступа в Oracle8i - это возможность во время работы динамически присоединить предикат (предложения where) как к одному, так и ко всем запросам к таблице или представлению. Таким образом, появилась возможность процедурной модификации запроса в процессе выполнения. Можно вычислить, кто выполняет запрос, откуда запрос выполняется, когда началось выполнение запроса, и сформировать предикат, соответствующий этим критериям. При использовании Контекстов Приложения можно незаметно через окружение (например, через роль, назначенную пользователю приложения) добавить дополнительную информацию, и получить доступ к ней через процедуру или предикат.

Примером детального контроля доступа может служить политика безопасности, которая определяет, какие строки могут быть доступны различным группам пользователей. Политика безопасности формирует предикат, вид которого зависит от соединенного с базой пользователя и группы, к которой он относится. Детальный контроль доступа позволяет при вводе запроса "select * from emp" различными пользователями преобразовать его к следующему виду:

Пользователь

Запрос динамически переписывается в

Замечания

Служащий

select * 
from ( select *
 
        from emp
 
       where ename = USER )

Служащие могут видеть только свои записи

Менеджер

select * 
 
 from ( select *
 
          from emp
 
         where mgr = ( select empno
 
                         from emp
 
                        where ename = USER )
 
            or ename = USER )

Менеджеры могут видеть свои записи и записи тех, кто работает под их руководством.

Контролер

select * 
 
 from (select *
 
         from emp
 
        where deptno =
 
            SYS_CONTEXT( ‘OurApp’, ‘Deptno’ ) )

Контролер может видеть любого в заданном отделе. Этот пример знакомит с синтаксисом получения переменных контекста приложения - встроенной функцией SYS_CONTEXT().

Почему используется эта возможность

Есть много причин, чтобы использовать этот механизм. Наиболее распространенные из них:

Способы использования этой возможности

В Oracle8i существует два типа детального контроля доступа:

Для того, чтобы воспользоваться этой возможностью, разработчик, кроме стандартных ролей connect и resource, должен иметь следующие привилегии:

Контексты приложения создаются простой SQL-командой

SQL> create context OurApp using Our_Context_Pkg;

OurApp - это имя контекста, а Our_Context_Pkg - это PL/SQL-пакет, через который устанавливаются значения контекста. Возможность использования контекстов приложения для детального контроля доступа имеет большое значение по двум причинам:

Пример 1. Реализация политики безопасности

Если требуется, чтобы политика безопасности позволяла пользователю, не являющемуся RLS_ADMIN, видеть только такие строки, “владельцем” которых он является, то необходимо выполнить команду:\

SQL> create function my_security_function( p_schema in varchar2,
  2     p_object in varchar2 ) return varchar2
  3  as
  4  begin
  5      if ( user = 'RLS_ADMIN' ) then
  6          return '';
  7      else
  8          return 'owner = USER';
  9      end if;
10  end;
11  /
Функция создана.

Предикат "where owner = USER" будет динамически добавляться ко всем запросам по таблице, с которой связана эта функция, что значительно уменьшает количество строк, доступных пользователю. Предикат NULL (пусто) возвращается только в том случае, когда на данный момент к базе данных присоединен пользователь RLS_ADMIN. Пустой возвращаемый предикат выглядит как "1=1" или "TRUE".

Для того, чтобы связать эту функцию с таблицей, необходимо использовать PL/SQL-процедуру "dbms_rls.add_policy". Например, имеется следующая таблица:

SQL> create table my_table
   2  (  data        varchar2(30),
   3     OWNER       varchar2(30) default USER
   4  )
   5  /
Table created.
SQL> grant all on my_table to public
   2  /
Grant succeeded.
SQL> insert into my_table ( data ) values ( 'Некоторыеданные' )
   2  /
1 row created.
SQL> insert into my_table ( data, owner )
  
2  values ( 'Some Data Owned by SCOTT', 'SCOTT' )
   
3  /
1 row created.
SQL> commit
  
2  /
Commit complete.
SQL> select * from my_table
   
2  /
DATA                             OWNER
------
------------------------------- ------------
Некоторые данные                 RLS
Некоторые данные владелеца SCOTT SCOTT
 Политику "My_Security_Policy" следует подключать следующим образом:
SQL> begin
 
2     dbms_rls.add_policy
 
3     ( object_schema   => 'RLS',
 
4       object_name     => 'MY_TABLE',
 
5       policy_name     => 'MY_POLICY',
 
6       function_schema => 'RLS',
 
7       policy_function => 'My_Security_Function',
 
8       statement_types => 'select, insert, update, delete' ,
 
9       update_check    => TRUE );
 
10  end;
 
11  /
 PL/SQL procedure successfully completed.

Теперь все DML-предложения, относящиеся к таблице EMP, будут иметь предикат, возвращаемый связанной функцией my_security_function, независимо от источника, вызвавшего DML-операцию (т.е. независимо приложения, получающего доступ к данным). Посмотрим на это в действии:

SQL> connect rls/rls
Connected.
SQL> select * from my_table
  
2  /
DATA                 OWNER
------
------------------- ------------
Некоторые данные     RLS

Итак, полученный результат показывает, что строки отфильтрованы надлежащим образом - текущий пользователь RLS может видеть только свои строки - он является их владельцем. Строки, владельцем которых является SCOTT, стали невидимы. Присоединимся теперь как учетная запись RLS_ADMIN:

SQL> connect rls_admin/rls_admin
Connected.
SQL> select * from rls.my_table
   
2  /
DATA                             OWNER
-------------------------------- ------------------
Некоторые данные                 RLS
Некоторые данные владельца SCOTT SCOTT

Результат показывает, что учетная запись RLS_ADMIN может видеть все данные, какие пожелает. Присоединимся опять учетной записью RLS и посмотрим, что произойдет при попытке создания данных, которые нельзя 'увидеть' (пользователь не являемся их владельцем):

SQL> connect rls/rls
Connected.
SQL> insert into my_table ( data ) values ( 'Некоторыеновыеданные' )
 
 2  /
1 row created.
SQL> insert into my_table ( data, owner )
   2  values ('Некоторые новые данные владельца SCOTT', 'SCOTT' )
   3  /
insert into my_table ( data, owner )
           *
ERROR at line 1:
ORA-28115: нарушение политики с опцией проверки
Ошибка ORA-28115 возникает, так как при добавлении политики было указано:

9       update_check    => TRUE );

по аналогии с созданием представления с включенной возможностью "CHECK OPTION". Такая политика позволяет создавать только те данные, которые можно выбрать. По умолчанию можно создавать данные, которые выбрать нельзя.

Часть 2 >>

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

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


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