|
Программирование >> Oracle
1508 Глава 23 Начиная с Oracle 8i появилась возможность выполнять процедуры с правами в1-вающего, что позволяет создавать процедуры, функции и пакеты, выполняющиеся с набором привилегий вызывающего, а не создателя. В этой главе мы рассмотрим: когда следует использовать процедуры с правами вызывающего, в том числе, для создания приложений, работающих со словарем данных, универсальных объектных типов и реализации собственных средств контроля доступа; когда следует использовать процедуры с правами создателя, с учетом их масштабируемости по сравнению с процедурами, работающими с правами вызывающего, а также возможностей по реализации защиты данных; как работают хранимые процедуры этих двух типов; проблемы, которые необходимо учитывать при выполнении процедур с правами вызывающего, в частности использование разделяемого пула, производительность процедур, необходимость расширенных средств обработки ошибок в коде, а также использование языка Java для реализации процедур, работающих с правами вызывающего. Пример Возможность выполнять код с правами вызывающего позволяет, например, создать хранимую процедуру, работающую с набором привилегий пользователя, который ее выполняет. В результате хранимая процедура может работать правильно и корректно для одного пользователя (который имеет доступ ко всем необходимым объектам), но не работать для другого (у которого такого доступа нет). Причина состоит в том, что доступ к базовым объектам проверяется не во время компиляции, а во время выполнения (правда, создатель должен иметь доступ к соответствующим объектам или хотя бы к объектам с такими же именами, чтобы PL/SQL-код вообще можно б1ло скомпилировать). Подобный доступ во время выполнения осуществляется с учетом привилегий и ролей текущего пользователя/схемы. Следует отметить, что работа с правами вызывающего не поддерживается для представлений и триггеров. Представления и триггеры создаются и работают только с правами создателя. Возможность работы с правами вызывающего легко реализовать и проверить, поскольку для этого необходимо добавить к процедуре или пакету всего одну строку. Рассмотрим, например, следующую процедуру, выдающую значения атрибутов контекста: CURRENT USER. Имя пользователя, с привилегиями которого работает сеанс. SESSION USER. Имя пользователя, зарегистрировавшегося и первоначально создавшего этот сеанс. Это значение в течение сеанса неизменно. CURRENT SCHEMA. Имя стандартной схемы, которая будет использоваться при разрешении неуточненных ссылок на объекты. Для создания процедуры, работающей с правами создателя, необходим следующий код: tkyte@TKYTE816> create or replace procedure definer proc 2 as Права в1зывающего и создателя 1509 3 begin 4 for x in 5 (select sys context(userenv, current user) current user, 6 sys context(userenv, session user) session user, 7 sys context(userenv, current schema) current schema 8 from dual) 9 loop 10 dbms output.put line(CurrentUser: 11 dbms output.put line(SessionUser: 12 dbms output.put line(Current Schema: 13 end loop; 14 end; 15 / x.current user); x.session user); x.current schema); Procedure created. tkyte@TKYTE816> grant execute Grant succeeded. on definer proc to scott; Для создания такой же процедуры, работающей немного изменить: с правами вызывающего, код надо tkyte@TKYTE816> create or replace procedure invoker proc 10 11 12 13 14 15 16 AUTHID begin CURRENT USER x in (select sys context(userenv, sys context(userenv, sys context(userenv, from dual) loop dbms output.put line(Current dbms output.put line(SessionUser: dbms output.put line(Current Schema: end loop; end; current user ) current user, session user) session user, current schema) current schema User: x.current user); x.session user); x.current schema); Procedure created. tkyte@TKYTE816> grant execute on invoker proc to scott; Grant succeeded. Вот и все; добавили одну строку, и процедура теперь будет выполняться с привилегиями и в пространстве имен вызывающего пользователя, а не создателя. Чтобы глубже понять, что это означает, выполним представленные выше процедуры и сравним выдаваемые ими результаты. Сначала процедура, работающая с правами создателя: tkyte@TKYTE816> connect scott/tiger scott@TKYTE816> exec tkyte.definer proc Current User: TKYTE Session User: SCOTT Current Schema: TKYTE PL/SQL procedure successfully completed. 1510 Глава 23 Внутри процедуры, работающей с правами создателя, текущий пользователь и схема, с привилегиями которой работает сеанс - TKTE. Пользователь, зарегистрировавшийся и начавший сеанс - SCO. Это значение в течение сеанса не меняется. При этом все неуточненные ссылки будут разрешаться в схеме TKYTE (например, запрос SELECT * FROM T будет разрешаться как SELECT * FROM TKYTE.T). Процедура, работающая с правами вызывающего, дает совсем другие результаты: scott@TKYTE816>exectkyte.invoker proc Gurrent User: SGOTT Session User: SGOTT Gurrent Schema: SGOTT PL/SQL procedure successfully completed. Текущий пользователь - SCOTT, а не TKYTE. Текущий пользователь в такой процедуре совпадает с пользователем, непосредственно выполняющим эту процедуру. Пользователь, зарегистрировавшийся и начавший сеанс - SCOTT, как и ожидалось. Текущая схема, однако, - тоже SCOTT, поэтому запрос SELECT * FROM T будет выполняться как SELECT * FROM SCOTT.T. Это показывает фундаментальное отличие процедур, работающих с правами вызывающего: процедура работает с правами пользователя, который ее вызвал. Кроме того, текущая схема также зависит от вызывающего. При выполнении этой процедуры разными пользователями она может обращаться к различным объектам. Интересно, как повлияет на эти процедуры явное изменение текущей схемы: scott@TKYTE816> alter session set current schema - system; Session altered. scott@TKYTE816>exectkyte.definer proc Gurrent User: TKYTE Session User: SGOTT Gurrent Schema: TKYTE PL/SQL procedure successfully completed. scott@TKYTE816>exectkyte.invoker proc Gurrent User: SGOTT Session User: SGOTT Gurrent Schema: SYSTEM PL/SQL procedure successfully completed. Как видите, результаты выполнения процедуры с правами создателя не изменились. В таких процедурах текущий пользователь и текущая схема статичны . Они жестко задаются при компиляции и не меняются в дальнейшем при изменении текущей среды. Процедура, работающая с правами вызывающего, более динамична. Текущий пользователь устанавливается во время выполнения, а текущая схема может меняться для каждого вызова, даже в пределах одного сеанса. Это очень мощное средство (при правильном и уместном использовании). Оно позволяет реализовать для хранимых процедур и пакетов PL/SQL поведение, более свойственное приложениям, написанным на Pro*C. Приложение, использующее Рго*С(или интерфейсы ODBC, JDBC - в общем, любое клиентское приложение на обычных про-
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |