СТАТЬЯ |
15.01.02
|
Детальный контроль доступа и контексты приложения (Часть 4)
©
Том Кайт
Статья была
опубликована в журнале OracleMagazine
Теперь присоединимся различными пользователями и протестируем функциональность приложения.
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
beginif ( g_sel_pred is NULL )
thenif ( 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,RESEARCHPL/SQL procedure successfully completed.
SQL> -- несмотря на то, что данные "видно"
SQL> -- их нельзя "изменить".SQL> exec rls.hr_app.updateSal
0 rows updatedPL/SQL procedure successfully completed.
SQL> -- нельзя удалить никакую информацию
SQL> exec rls.hr_app.deleteAll
0 rows deletedPL/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 onSQL> -- Для начала попробуем стать менеджером
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,RESEARCHPL/SQL procedure successfully completed.
SQL> -- Следующая операция показывает, что некоторые записи можно
SQL> -- изменить. Затем снова выполним listEmps для того, чтобы увидеть,
SQL> -- какие строки изменились (только те, которые подчинены напрямую)SQL> exec rls.hr_app.updateSal
2 rows updatedPL/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,RESEARCHPL/SQL procedure successfully completed.
SQL> -- так как мы не являемся контролером, то,
SQL> -- согласно заданным правилам, нельзя никого удалитьSQL> exec rls.hr_app.deleteAll
0 rows deletedPL/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, можно:
И, наконец, присоединимся как контролер и посмотрим на поведение приложения при работе с этой ролью:
SQL> -- Присоединимся как контролер
SQL> connect rls_king/rls_king
Connected.SQL> -- Подключим возможность вывода на экран из PL/SQL
SQL> set serveroutput onSQL> -- Для начала, попробуем стать контролером
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,SALESPL/SQL procedure successfully completed.
SQL> -- следующая операция показывает, что можно изменить любую запись
SQL> -- в любом отделе, так как пользователь для всех
SQL> -- является контролером
SQL> -- далее снова запустим listEmps, чтобы увидеть, какие
SQL> -- строки изменились (все)SQL> exec rls.hr_app.updateSal
14 rows updatedPL/SQL procedure successfully completed.
SQL> -- так как пользователь - контролер, то он может
SQL> -- удалить кого-нибудь согласно заданным правилам
SQL> -- При удалении ВСЕХ не удаляется 'я',
SQL> -- т.е. текущий пользовательSQL> exec rls.hr_app.deleteAll
13 rows deletedPL/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:
При написании предикатных функций я часто пользуюсь одной утилитой - это пакет ‘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 и выше.
Дополнительную информацию Вы можете получить в компании Interface Ltd.
Обсудить на форуме
Oracle
Отправить ссылку на страницу по e-mail
Interface Ltd. Отправить E-Mail http://www.interface.ru |
|
Ваши
замечания и предложения отправляйте
автору По техническим вопросам обращайтесь к вебмастеру Документ опубликован: 15.01.02 |