Oracle
Oracle

Новое в 8i: полномочия предъявителя в PL/SQL

Владимир Пржиялковский
16 февраля 2000 г.

Версия Oracle 8i (8.1), выпущенная в 1999 году после долгих задержек, содержит большой объем нововведений (как утверждает сама фирма, “более 150”). Многие из них коснулись такой базовой компоненты, как PL/SQL. Несмотря на появление у разработчика альтернативы в виде Java (говорят, в фирме Oracle долго спорили по поводу перспектив выбора языка программирования для системы, но, в конце концов, пришли к Соломонову решению), PL/SQL остается наиболее эффективным встроенным языком в Oracle, превосходя по своим возможностям аналоги конкурентов – Informix 4GL и Sybase/Microsoft Transact-SQL. Тем обиднее, что некоторые качества PL/SQL появляются только сейчас, в версии 8.1, а не были встроены 10 лет назад, в результате чего разработчики оказались лишены, казалось бы, естественных возможностей и тратили свои усилия на придумывание ухищрений, ныне лишенных смысла. Особенно обидно, когда речь идет о синтаксических конструкциях, исчерпывающихся всего парой слов, но меняющих, несмотря на это, значительную часть архитектуры создаваемого кода.

Одно из таких “микро-нововведений”, приближающих логику функционирования кода на PL/SQL логике исполнения программ в Unix, рассмотрим сегодня. Речь идет о так называемых “полномочиях предъявителя” (invoker rights) для процедур на PL/SQL.
 
 

Полномочия создавшего, прежде единственные

В версиях 7 и 8.0 единственной логикой контроля доступа к объектам БД из процедуры на PL/SQL была логика “полномочия создавшего” (definer rights). Процедура всегда создается от какого-нибудь имени пользователя Oracle. Вызываться она может и другим пользователем (владеющим на это правом, данным с помощью предложения GRANT EXECUTE), но при попытке работать с объектами БД – таблицами, последовательностями – права на доступ к этим объектам в предыдущих версиях соответствовали полномочиям создателя процедуры. (Сейчас это верно только по умолчанию, если специально не оговорить другую схему работы). Вот некоторые свойства такой модели полномочий:

Такая логика работы имеет определенные преимущества. Вот, примерно, как их формулировали в фирме Oracle: Звучит разумно.
 
  Проблемы с полномочиями создавшего

Тем не менее, 90% разработчиков сознаются, что использование модели “полномочий создавшего” доставляет им непрерывную головную боль из-за необходимости придумывать специальные ухищрения, в конечном счете негативно сказывающиеся на архитектуре создаваемой системы.

Вот типичный случай. Пусть создается система по схеме “центр – территориальные отделения”. Все территориальные отделения (ТО) однородны по сути и работают с одними и теми же программами, но каждое со своими собственными данными. Пусть все обслуживается одним сервером БД (например, работа идет через Internet). Тогда логично (и правильно с точки зрения безопасности и разграничения доступа) дать каждому ТО по самостоятельному имени в БД и по отдельной схеме данных. Другое дело, что схемы эти будут у всех одинаковы. И одинаковым должен быть код программ, работающих с данными.

Для кода напрашивается (логически правильное) решение: создать отдельную схему БД, скажем, с именем COMMON, и в ней создавать сами PL/SQL-пакеты и процедуры. Но как ими будут пользоваться ТО ? Обратиться к процедуре просто new_employee ТО не может, так как процедура ему не принадлежит. Обратиться COMMON.new_employee тоже нельзя, потому что схема COMMON не владеет данными вызывающего ТО, а кроме того помещать в код приложения имя схемы тоже не всегда правильно.

Прежде в таких ситуациях приходилось копировать пакеты из COMMON в схемы ТО (см. рисунок) – во многих отношениях не лучшее решение, но часто единственно приемлемое.


 
 

Полномочия предъявителя

Синтаксис указания полномочий предъявителя чрезвычайно прост: в заголовке процедуры или функции перед словом IS или AS надо написать AUTHID CURRENT_USER. (Соответственно появившееся вариантное указание AUTHID DEFINER вступает в силу при отсутствии указаний). Модель прав предъявителя работает по следующим правилам:

/* Basic demonstration of AUTHID CURRENT_USER feature */

CONNECT demo/demo
CREATE PROCEDURE dummy1 IS
BEGIN
DBMS_OUTPUT.put_line ('Dummy1 owned by demo');
END;
/
GRANT execute on dummy1 to public;
CONNECT scott/tiger
CREATE PROCEDURE dummy1 IS
BEGIN
DBMS_OUTPUT.put_line ('Dummy1 owned by scott');
END;
/
GRANT execute on dummy1 to public;
CREATE PROCEDURE dummy2 AUTHID CURRENT_USER
IS
BEGIN
dummy1;
END;
/
GRANT execute on dummy2 to public;
EXEC scott.dummy2
CONNECT demo/demo
SET serveroutput on
EXEC scott.dummy2

Результаты вызова dummy2 от имени SCOTT и от имени DEMO разные.

Совсем по-другому будет выглядеть теперь схема использования программ территориальными отделениями (см. рисунок).


 
 

Какую модель когда использовать ?

Применение модели “полномочий предъявителя” возможно и в других ситуациях, помимо приведенной. Оно полезно, когда администратор (или кто-нибудь из разработчиков) создает программы общего назначения для всех пользователей. Вот еще одна простая иллюстрация из Стивена Фойерштайна:

CREATE OF REPLACE PROCEDURE runddl (ddl_in in VARCHAR2)
AUTHID CURRENT_USER
IS
BEGIN
EXECUTE IMMEDIATE ddl_in;
END;
/

EXECUTE IMMEDIATE – еще одно нововведение версии 8i, требующее особого разговора; здесь же важно, что мы имеем возможность дать всем пользователям общую и полезную процедуру, не утруждая себя кухней проверки прав. Вся ответственность за корректное обращение с данными ложится на пользователя, вызвавшего процедуру.

Но вернемся к перечню “преимуществ модели полномочий создавшего” выше. Он не теряет своей актуальности, и отказываться от этой модели полностью было бы неразумно. Очевидно, что несколько запоздалое нововведение Oracle добавляет разработчику не одну, а две дополнительные возможности для построения архитектуры программной системы: кроме возможности использования чистой модели полномочий создавшего (как раньше) появляется и возможность использования чистой модели полномочий предъявителя, и возможность комбинированного использования обеих моделей. Последний вариант – самый неоднозначный в плане конкретной реализации, так как теоретически охватывает все возможные комбинации разделения/обобществления (в “центральной” схеме) данных и разделения/обобществления кода. Выбор из этого множества конкретной комбинации для своей задачи должен быть сделан разработчиком взвешенно и ответственно.
 

Литература

    Oracle PL/SQL Programming. Steven Feuerstein. O’Reilly & Associates, October 1999.
    The Right Stuff: Invoker-Rights Procedures. Jason Couchman. Oracle Magazine, January/February 2000
    Документация по Oracle

За дополнительной информацией обращайтесь в Interface Ltd.


Interface Ltd.

Tel: 7+(095) 135-55-00, 135-25-19
E-mail: mail@interface.ru
http://www.interface.ru
Подготовили: tkachev@interface.ru
Дата: 16.02.2000