| 
div.main {margin-left: 20pt; margin-right: 20pt}
Новое в 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: 
  Такая модель позволяет улучшить контроль работы с данными. Работу с 
  таблицей можно организовать так, что изменение ее содержимого станет 
  пользователям Oracle возможно только посредством обращения к определенным 
  процедурам. 
  Процедуры работают быстро, потому что не тратят время на проверку прав 
  доступа во время исполнения. 
  Разработчик не должен беспокоиться о том, что может быть ненамеренно 
  модифицирована не та таблица – все объекты жестко 
предопределены.Звучит разумно.       Проблемы с 
полномочиями создавшего 
 Тем не менее, 90% разработчиков сознаются, что использование модели 
“полномочий создавшего” доставляет им непрерывную головную боль из-за 
необходимости придумывать специальные ухищрения, в конечном счете негативно 
сказывающиеся на архитектуре создаваемой системы. 
 Вот типичный случай. Пусть создается система по схеме “центр – 
территориальные отделения”. Все территориальные отделения (ТО) однородны по сути 
и работают с одними и теми же программами, но каждое со своими собственными 
данными. Пусть все обслуживается одним сервером БД (например, работа идет через 
Internet). Тогда логично (и правильно с точки зрения безопасности и 
разграничения доступа) дать каждому ТО по самостоятельному имени в БД и по 
отдельной схеме данных. Другое дело, что схемы эти будут у всех одинаковы. И 
одинаковым должен быть код программ, работающих с данными. 
 Для кода напрашивается (логически правильное) решение: создать отдельную 
схему БД, скажем, с именем COMMON, и в ней создавать сами PL/SQL-пакеты и 
процедуры. Но как ими будут пользоваться ТО ? Обратиться к процедуре просто 
new_employee ТО не может, так как процедура ему не принадлежит. Обратиться 
COMMON.new_employee тоже нельзя, потому что схема COMMON не владеет данными 
вызывающего ТО, а кроме того помещать в код приложения имя схемы тоже не всегда 
правильно. 
 Прежде в таких ситуациях приходилось копировать пакеты из COMMON в схемы ТО 
(см. рисунок) – во многих отношениях не лучшее решение, но часто единственно 
приемлемое. 
     
   
 Полномочия предъявителя 
 Синтаксис указания полномочий предъявителя чрезвычайно прост: в заголовке 
процедуры или функции перед словом IS или AS надо написать AUTHID CURRENT_USER. 
(Соответственно появившееся вариантное указание AUTHID DEFINER вступает в силу 
при отсутствии указаний). Модель прав предъявителя работает по следующим 
правилам: 
  Для разрешения внешних ссылок при выполнении программы анализируются роли 
  пользователя, запустившего программу. 
  Предложение AUTHID можно использовать лишь в заголовках отдельных 
  программ, пакетов и спецификаций объектного типа. Предложение AUTHID нельзя 
  использовать в отдельных программах или методах из состава пакета или описания 
  типа объекта. 
  Вот перечень предложений, для которых права доступа проверяются 
  динамически во время исполнения программы: 
  
    SELECT, INSERT, UPDATE, DELETE 
    LOCK TABLE 
    OPEN и OPEN-FOR для курсоров 
    EXECUTE IMMEDIATE и OPEN-FOR-USING предложения динамического SQL 
    SQL-предложения, транслируемые программой 
  Внешние ссылки на PL/SQL-программы и методы объектов разрешаются во время 
  компиляции по правилам создавшего. Вот как примером разъясняет такое положение 
  дел Стивен Фойерштайн (применение предложения AUTHID CURRENT_USER выделено 
  серым фоном): /* 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 добавляет 
разработчику не одну, а две дополнительные возможности для 
построения архитектуры программной системы: кроме возможности использования 
чистой модели полномочий создавшего (как раньше) появляется и возможность 
использования чистой модели полномочий предъявителя, и возможность 
комбинированного использования обеих моделей. Последний вариант – самый 
неоднозначный в плане конкретной реализации, так как теоретически охватывает все 
возможные комбинации разделения/обобществления (в “центральной” схеме) данных и 
разделения/обобществления кода. Выбор из этого множества конкретной комбинации 
для своей задачи должен быть сделан разработчиком взвешенно и ответственно. 
   
 
 |