(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

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

Источник: Oracle Magazine RE
Том Кайт

Часть 3

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

SQL> @rls_adams
SQL> -- Присоединимся как служащий, у которого нет способности управлять.
SQL> connect rls_adams/rls_adams
Connected.
SQL> set serveroutput on
SQL> -- Сначала попробуем стать менеджером
SQL> -- Мы не являемся менеджером, поэтому стать им
SQL> -- не разрешается
SQL> exec rls.set_role( 'mgr' )
BEGIN rls.set_role( 'mgr' ); END;
*
ERROR at line 1:
ORA-20002: Вы не менеджер
ORA-06512: at "RLS.SET_ROLE", line 53
ORA-06512: at line 1

Таким образом, результат показывает, что нельзя получить роль, не предназначенную для текущего пользователя. Чтобы убедиться, что ни к каким данным нет доступа, попробуем теперь запросить что-нибудь, и посмотрим, что произойдет:

SQL> -- теперь посмотрим, что произойдет при попытке выполнить
SQL> -- что-нибудь без получения роли
SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.EMPNO = 7876
------ Данные таблицы Emp, которые можно увидеть -----
BEGIN rls.hr_app.listEmps; END;
*
ERROR at line 1:
ORA-28112: ошибка при выполнении функции политики
ORA-06512: at "RLS.HR_APP", line 18
ORA-06512: at line 1

Появилось сообщение об ошибке. Это сообщение возникло, потому что так написана предикатная функция:

function select_function( p_schema in varchar2,
                         p_object in varchar2 ) return varchar2
is
begin
    if ( g_sel_pred is NULL )
   then
        if ( sys_context( g_app_ctx, 'RoleName' ) = 'EMP' )
        then
           …
        elsif ( sys_context( g_app_ctx, 'RoleName' ) = 'MGR' )
        then

        elsif ( sys_context( g_app_ctx, 'RoleName' ) = 'HR_REP' )
        then

        else
            raise_application_error( -20005, 'Рольнеустановлена' );
       end if;
   end if;
    return g_sel_pred;
end;

Полученный результат - это результат выполнения raise_application_error в предикатной функции. Конечный пользователь получает сообщение об ошибке ORA-28112. Далее, в следующей секции, мы рассмотрим, как обнаружить эти ошибки и отладить их.

Далее установим такую роль, чтобы можно было что-нибудь сделать, и попробуем выполнить эти же операции:

SQL> -- Теперь установим корректную роль и выполним что-нибудь
 SQL> exec rls.set_role( 'emp' );
PL/SQL procedure successfully completed.
SQL> -- посмотрим контекст и данные,
SQL> -- которые можно видеть - это только одна запись
SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.ROLENAME = EMP
HR_APP_CTX.EMPNO = 7876
------ Данные таблицы Emp, которые можно увидеть -----
RLS_ADAMS,1100,RESEARCH
PL/SQL procedure successfully completed.
 SQL> -- несмотря на то, что данные "видно" 
SQL> -- их нельзя "изменить".
SQL> exec rls.hr_app.updateSal
0 rows updated
PL/SQL procedure successfully completed.
SQL> -- нельзя удалить никакую информацию
 SQL> exec rls.hr_app.deleteAll
0 rows deleted
PL/SQL procedure successfully completed.
SQL> -- нельзя ничего создать
SQL> exec rls.hr_app.insertNew(20)
BEGIN rls.hr_app.insertNew(20); END;
*
ERROR at line 1:
ORA-28115: нарушение политики с опцией проверки
ORA-06512: at "RLS.HR_APP", line 44
ORA-06512: at line 1

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

Далее присоединимся как MGR и посмотрим, что произойдет:

SQL> -- Присоединимся как менеджер
SQL> connect rls_jones/rls_jones
Connected.
SQL> -- Включим возможность вывода на экран из PL/SQL
SQL> set serveroutput on
SQL> -- Для начала попробуем стать менеджером
SQL> -- мы являемся менеджером, так как на этот раз нам разрешено
SQL> -- статьим
SQL> exec rls.set_role( 'mgr' )
PL/SQL procedure successfully completed.
SQL> -- посмотрим контекст и данные,
SQL> -- которые можно видеть. На этот раз - более одной строки.
SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.ROLENAME = MGR
HR_APP_CTX.EMPNO = 7566
------ Данные таблицы Emp, которые можно увидеть -----
RLS_SMITH,800,RESEARCH
RLS_JONES,2975,RESEARCH
RLS_SCOTT,3000,RESEARCH
RLS_ADAMS,1100,RESEARCH
RLS_FORD,3000,RESEARCH
PL/SQL procedure successfully completed.
SQL> -- Следующая операция показывает, что некоторые записи можно 
SQL> -- изменить. Затем снова выполним listEmps для того, чтобы увидеть,
SQL> -- какие строки изменились (только те, которые подчинены напрямую)
SQL> exec rls.hr_app.updateSal
2 rows updated
 PL/SQL procedure successfully completed.
 SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.ROLENAME = MGR
HR_APP_CTX.EMPNO = 7566
------ Данные таблицы Emp, которые можно увидеть -----
RLS_SMITH,800,RESEARCH
RLS_JONES,2975,RESEARCH
RLS_SCOTT,9999,RESEARCH
RLS_ADAMS,1100,RESEARCH
RLS_FORD,9999,RESEARCH
PL/SQL procedure successfully completed.
SQL> -- так как мы не являемся контролером, то, 
SQL> -- согласно заданным правилам, нельзя никого удалить
SQL> exec rls.hr_app.deleteAll
0 rows deleted
PL/SQL procedure successfully completed.
SQL> -- так как мы не являемся контролером, то, 
SQL> -- согласно заданным правилам, нельзя никого вставить
SQL> exec rls.hr_app.insertNew(20)
BEGIN rls.hr_app.insertNew(20); END;
*
ERROR at line 1:
ORA-28115: нарушение политики с опцией проверки
ORA-06512: at "RLS.HR_APP", line 44
ORA-06512: at line 1

Таким образом, теперь нам, как MGR, можно:

  • Просматривать не только свои данные. Видно всех, кто нам подчинен и тех, кто подчинен нашим подчиненным и так далее (по иерархии).
  • Изменять некоторые данные. Точнее, можно изменять только те записи, которые относятся к нашим непосредственным подчиненным - что и требуется.
  • Ни над какими данными все еще нельзя выполнить DELETE или INSERT - что и требуется

И, наконец, присоединимся как контролер и посмотрим на поведение приложения при работе с этой ролью:

SQL> -- Присоединимся как контролер
SQL> connect rls_king/rls_king
Connected.
SQL> -- Подключим возможность вывода на экран из PL/SQL
SQL> set serveroutput on
SQL> -- Для начала, попробуем стать контролером
SQL> -- Теперь мы являемся контролером, так как
SQL> -- стать им разрешено
SQL> exec rls.set_role( 'hr_rep' )
PL/SQL procedure successfully completed.
SQL> -- посмотрим контекст и данные,
SQL> -- которые можно видеть.  На этот раз видно все строки, так как
SQL> -- пользователь - контолер.
SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.ROLENAME = HR_REP
HR_APP_CTX.EMPNO = 7839
------ Данные таблицы Emp, которые можно увидеть -----
RLS_CLARK,2450,ACCOUNTING
RLS_KING,5000,ACCOUNTING
RLS_MILLER,1300,ACCOUNTING
RLS_SMITH,800,RESEARCH
RLS_JONES,2975,RESEARCH
RLS_SCOTT,9999,RESEARCH
RLS_ADAMS,1100,RESEARCH
RLS_FORD,9999,RESEARCH
RLS_ALLEN,1600,SALES
RLS_WARD,1250,SALES
RLS_MARTIN,1250,SALES
RLS_BLAKE,2850,SALES
RLS_TURNER,1500,SALES RLS_JAMES,950,SALES
PL/SQL procedure successfully completed.
SQL> -- следующая операция показывает, что можно изменить любую запись
SQL> -- в любом отделе, так как пользователь для всех
SQL> -- является контролером
SQL> -- далее снова запустим listEmps, чтобы увидеть, какие
SQL> -- строки изменились (все)
SQL> exec rls.hr_app.updateSal
14 rows updated
PL/SQL procedure successfully completed.
SQL> -- так как пользователь - контролер, то он может
SQL> -- удалить кого-нибудь согласно заданным правилам
SQL> -- При удалении ВСЕХ не удаляется 'я',
SQL> -- т.е. текущий пользователь
SQL> exec rls.hr_app.deleteAll
13 rows deleted
PL/SQL procedure successfully completed.
SQL> -- так как пользователь - контролер, то он может 
SQL> -- вставить кого-нибудь согласно заданным правилам
SQL> exec rls.hr_app.insertNew(20)
PL/SQL procedure successfully completed.
SQL> -- посмотрим на результат изменения, удаления
SQL> -- и последующей вставки
SQL> exec rls.hr_app.listEmps
------ КонтекстСессии ----------
HR_APP_CTX.ROLENAME = HR_REP
HR_APP_CTX.EMPNO = 7839
------ Данные таблицы Emp, которые можно увидеть -----
RLS_KING,9999,ACCOUNTING
,1111,RESEARCH
PL/SQL procedure successfully completed.

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

Обработка ошибок и отладка

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

Во время разработки процедур детального контроля доступа могут появиться четыре основных кода ошибок Oracle:

  • ORA-28110: функция политики или пакет <имя_функции> содержит ошибки. Это означает, что связанный с политикой пакет или функция содержат ошибки и не могут быть скомпилированы. Ошибки можно увидеть, если выполнить "show errors function <имя_функции>" или "show errors package body <имя_пакета>".
  • ORA-28112: ошибка при выполнении функции политики. Возникает, если ошибка появляется во время выполнения предикатной функции. Это может произойти, например, когда при выполнении предложения SELECT INTO, находящегося внутри PL/SQL-функции, строки не найдены, и для этой ситуации нет обработчика исключений. Функция распространяет исключение NO_DATA_FOUND обратно в точку вызова (в ядро базы данных), и база данных инициирует ошибку ORA-28112.
  • ORA-28113: предикат политики содержит ошибки. Эта ошибка возникает, когда предикатная функция успешно возвращает условие where, но при его добавлении к SQL-запросу внутри него обнаруживаются ошибки. Например, в том случае, когда возвращается условие where типа "x = 5", а таблица, с которой оно ассоциируется, не имеет столбца "x", буден получен код ошибки ORA-28113.
  • ORA-28106: входное значение аргумента #2 неверно. Эта ошибка возникает при обращении к dbms_session.set_context, если имя атрибута не является правильным идентификатором Oracle. Имена атрибутов контекста приложения должны быть правильными идентификаторами (т.е. их можно использовать для назначения имен столбцов таблиц или PL/SQL-переменных). Необходимо только изменить имя атрибута. Например, в приложении могут использоваться атрибуты ‘SEL’, ‘INS’, ‘UPD’ и ‘DEL’ вместо ‘SELECT’, ‘INSERT’ и так далее, потому что ‘SELECT’ не является правильным именем идентификатора Oracle.

При написании предикатных функций я часто пользуюсь одной утилитой - это пакет ‘debug’. Этот пакет, автором которого является Кристофер Бек (Christopher Beck) из Oracle, позволяет вставить в код предложения команду ‘print’. Кроме того, этот пакет позволяет широко использовать предложения типа:

create function foo …
as
   …
begin
     debug.f( ‘Входвпроцедуру foo’ );
     if ( some_condition ) then
         l_predicate := ‘x=1’;
     end if; 
     debug.f( ‘Переходквозвратупредиката "%s"’, l_predicate );
     return l_predicate;
end;

Таким образом, работа процедуры debug.f похожа на с-функцию printf, а сама она использует пакет UTL_FILE. На сервере базы данных она создает управляемые программистом файлы трассировки. Файлы трассировки содержат отладочные предложения, которые можно использовать для просмотра выполненных действий при выполнении кода. Так как программный код находится в ядре базы данных, отладка может оказаться сложной. Наличие файлов трассировки может сэкономить много времени. Скрипты, которые можно загрузить (см. далее в этом же разделе) содержат отладочный пакет и комментарии по его установке и использованию.

"За" и "Против"

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

За

Против

Упрощает разработку приложения - переносит управление доступом из приложения на уровень данных.

Отладка может оказаться сложной, так как детальный контроль доступа осуществляется в фоновом режиме. Для этой цели более подходят пакеты типа ‘debug’, о которых идет речь в секции диагностики и отладки.

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

Допускает значительные изменения политики безопасности без влияния на клиентские приложения.

Упрощает управление объектами базы данных. Уменьшается общее число объектов базы данных, необходимых для поддержки приложения.

Хорошо работает. Использование контекстов приложения позволяет воспользоваться преимуществами разделяемого SQL.

Скрипты

Для того, чтобы получить все скрипты, используемые в этой статье, загрузите tar-файл. Пожалуйста, непременно прочитайте файл README.TXT, входящий в состав архива. Tar-файл можно открыть под Windows с помощью WinZip версии 6.0 и выше.



 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 14.01.2002 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Personal Edition Named User Plus License
Oracle Database Standard Edition 2 Processor License
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus Software Update License & Support
ABBYY FineReader 14 Standard Full
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Delphi - проблемы и решения
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100