Программирование >>  Oracle 

1 ... 359 360 361 [ 362 ] 363 364 365 ... 469


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 - в общем, любое клиентское приложение на обычных про-



1 ... 359 360 361 [ 362 ] 363 364 365 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика