Модели разрешений / прав Oracle и программирование на PL/SQL

Модели разрешений / прав Oracle и программирование на PL/SQL

СУБД Oracle поддерживает две модели разрешений / прав доступа. По умолчанию используется модель прав создателя (она была единственной до выхода Oracle8i). В этой модели хранимая программа работает с правами своего владельца (или создателя). Другая модель разрешений использует привилегии пользователя, вызвавшего программу; она называется моделью прав вызывающего.



Очень важно понимать особенности обеих моделей, потому что во многих приложениях PL/SQL возможно их сочетание. Давайте изучим эти модели более подробно — это поможет вам определить, когда должна использоваться каждая модель.

 

Модель разрешений создателя

Перед выполнением хранимая программа должна быть откомпилирована и записана в базу данных. Поэтому она всегда сохраняется в конкретной схеме или с конкретной учетной записью пользователя, даже если в ней имеются ссылки на объекты других схем. При использовании модели разрешений создателя действуют следующие правила:

  •  Разрешение всех внешних ссылок в программе выполняется во время компиляции, с использованием непосредственно предоставленных привилегий схемы, в которой эта программа компилируется.
  •  Роли базы данных полностью игнорируются при компиляции хранимых программ. Все привилегии, необходимые программе, должны предоставляться непосредственно создателю (владельцу) программы.
  •  При запуске программы, откомпилированной с использованием модели разрешений создателя (по умолчанию), ее команды SQL выполняются с разрешениями схемы, которой принадлежит эта программа.
  •  Хотя на выполнение компиляции программы требуется особое разрешение, привилегию EXECUTE, позволяющую выполнять эту программу, можно предоставить другим схемам и ролям.

На Рис. 1 показано, как использовать модель разрешений создателя для управления доступом к объектам базы данных. Все данные заказа хранятся в схеме OEData, а код ввода заказов хранится в схеме OECode. Владельцу схемы OECode предоставляются непосредственные привилегии, необходимые для компиляции пакета Order_Mgt и позволяющие вводить и отменять заказы.

Для обеспечения корректного обновления таблицы заказов необходимо запретить прямой доступ к ней (через роли или привилегии) из всех схем, кроме OECode. Предположим, что из схемы Sam_Sales нужно просмотреть все открытые заказы и закрыть те из них, которые были сделаны раньше определенной даты. Ассоциированный с этой схемой пользователь Sam не может выполнить команду DELETE из процедуры Close_Old_Orders; вместо этого он должен вызвать процедуру Order_Mgt.cancel.

 

Управление доступом к данным в модели разрешений создателя

Рис. 1. Управление доступом к данным в модели разрешений создателя

 

Преимущества модели разрешений создателя

В некоторых ситуациях просто не обойтись без модели разрешений создателя, обладающей рядом преимуществ в сравнении с моделью разрешений вызывающего:

  •  Разработчик имеет больше возможностей для управления доступом к структурам данных и может быть уверен, что изменение содержимого таблицы может осуществляться только через созданный им программный интерфейс (обычно пакет).
  •  Производительность приложения значительно повышается, поскольку ядру PL/ SQL не приходится во время выполнения проверять наличие разрешений на доступ к объектам или, что не менее важно, выяснять, с какой именно таблицей должна работать программа (поскольку одна таблица accounts может очень сильно отличаться от другой одноименной таблицы).
  •  Не нужно беспокоиться о том, что программа обратится не к той таблице. При использовании разрешений создателя программный код будет обрабатывать те же структуры данных, с которыми работали бы команды SQL, выполняемые из SQL*Plus (или другого приложения).

 

Недостатки модели разрешений создателя

Впрочем, у модели создателя также имеются свои недостатки.

 

Куда исчезла таблица?

Попытаемся разобраться, какое значение имеют перечисленные правила использования модели разрешений создателя для разработчика программ PL/SQL в его повседневной работе. Разработчики нередко пишут код, который выполняет обработку таблиц и представлений из других схем, создавая для них общие синонимы, которые попросту скрывают схемы. Привилегии при этом предоставляются через роли базы данных.

Эта распространенная модель имеет несколько неприятных особенностей. Предположим, что в сети вашей компании управление доступом к объектам реализовано посредством ролей. При работе с таблицей accounts вы можете выполнить в SQI*Plus такой запрос:

SQL> SELECT account#, name FROM accounts;

Однако если эту же таблицу (и даже тот же запрос) использовать в процедуре, PL/SQL выдаст сразу два сообщения об ошибках:

SQL> CREATE OR REPLACE PROCEDURE show_accounts
  2  IS
  3  BEGIN
  4     FOR rec IN (SELECT account#, name FROM accounts)
  5     LOOP
  6        DBMS_OUTPUT.PUT_LINE (rec.name);
  7     END LOOP;
  8  END;
  9  /

Warning: Procedure created with compilation errors.

SQL> sho err
Errors for PROCEDURE SHOW_ACCOUNTS:

LINE/COL ERROR
-------- ------------------------------------------------------
4/16     PL/SQL: SQL Statement ignored
4/43     PLS-00201: identifier 'ACCOUNTS' must be declared

Странно, не правда ли? Проблема заключается в том, что таблица ACCOUNTS на самом деле входит в состав другой схемы; для получения доступа к данным вы использовали синонимы и роли, но это не сработало. Так что если вы когда-нибудь столкнетесь с подобной ситуацией, просто обратитесь к администратору базы данных или владельцу объекта и попросите предоставить вам необходимые привилегии.

 

Проблемы с сопровождением кода

Предположим, в каждом филиале вашей компании используется собственная схема базы данных. Вы построили большой объем кода, который используется каждым филиалом для сбора и обработки своих, характерных только для него данных. Во всех схемах имеются собственные таблицы с одинаковой структурой, но с разными данными. Такая архитектура была выбрана как для обеспечения безопасности данных, так и для упрощения их передачи через промежуточные табличные пространства.

Теперь нам хотелось бы адаптировать этот код, чтобы сопровождение приложения требовало минимума времени и усилий. Для этого можно поместить его в одну схему и предоставить доступ к нему из объектов всех схем филиалов.

К сожалению, при использовании модели разрешений создателя так поступить невозможно. Если поместить код в определенную схему и задать для объектов всех схем филиалов право EXECUTE, то все они смогут работать с любым набором таблиц, указанных в центральной схеме (с набором одного филиала или, что более вероятно, с набором фиктивных таблиц-заготовок). Это очевидно нежелательно. Придется добавлять весь код в каждую региональную схему, как показано на Рис. 2.

Не стоит и говорить, каким кошмаром станет сопровождение и модификация такого кода. Конечно, модель разрешений вызывающего обеспечит более удобное решение.

 

Динамический SQL и разрешения создателя

Еще одним типичным источником проблем, связанных с разрешениями создателя, является динамический SQL. Предположим, мы создаем обобщенную программу для выполнения команд DDL (да, с точки зрения безопасности эта идея нежелательна, но она демонстрирует нежелательные последствия этого учебного примера):


PROCEDURE execDDL (ddl_string IN VARCHAR2)
IS
BEGIN
    EXECUTE IMMEDIATE ddl_string;
END;

 

Дублирование кода при использовании модели разрешений создателя

Рис. 2. Дублирование кода при использовании модели разрешений создателя

 

Протестировав этот код в своей схеме, мы решаем, что им могут пользоваться и другие разработчики. Откомпилировав его в схеме COMMON (которая используется для всего общедоступного кода), мы передаем разрешение на его выполнение пользователю PUBLIC, создаем общий синоним и рассылаем по электронной почте сообщение о новой замечательной программе.

Несколько недель спустя начинают поступать сообщения от коллег: «Я просил создать таблицу, и код выполнился без ошибок, но таблицы почему-то нет» или «Я просил удалить таблицу, но программа ответила, что такой таблицы не существует, хотя DESCRIBE для нее выполняется». В общем, идея ясна. Получив доступ к объектам схемы COMMON, вы обнаруживаете там все объекты, которые пользователи пытались создать с помощью его процедуры. Оказывается, если при вызове процедуры execddl пользователь попро­сит создать таблицу и не укажет имя собственной схемы, процедура создаст таблицу в схеме COMMON. Иначе говоря, вызов

EXEC execddl ('CREATE TABLE newone (rightnow DATE)')

создаст таблицу newone в схеме COMMON. Вызов вида

EXEC execddl ('CREATE TABLE scott.newone (rightnow DATE)')

мог бы решить проблему, но он завершается сообщением об ошибке (если только для схемы COMMON не предоставлена привилегия CREATE ANY TABLE). Увы, наша попытка поделиться с другими полезным кодом очень быстро усложнилась. А как было бы здорово, если бы все могли запускать ее с собственными привилегиями (а не с привилегиями схемы COMMON), не устанавливая собственную копию кода этой процедуры.

 

Повышение привилегий и внедрение SQL

Если ваша программа выполняет динамический код SQL, зависящий от явно предоставляемых привилегий владельца, а вы полагаете, что модель прав создателя более уместна, — сделайте паузу и обсудите свое решение с коллегами. Старайтесь избегать создания процедур (вроде приведенной выше) в схеме SYS или любой другой схеме с системными привилегиями — они могут послужить «черным ходом» для повышения привилегий при передаче непредвиденного, но формально допустимого ввода.

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

 

Модель разрешений вызывающего

Иногда программы должны выполняться с привилегиями пользователя, запустившего программу, а не владельца этой программы. В таких случаях следует выбирать модель разрешений вызывающего. Суть ее заключается в том, что разрешение всех внешних ссылок в командах SQL и программах PL/SQL выполняется в соответствии с привилегиями схемы вызывающего программу пользователя, а не владельца схемы, в которой эта программа определена.

Отличие модели разрешений вызывающего от модели разрешений создателя показано на Рис. 3. Вспомните, что на Рис. 2 для получения возможности обрабатывать таблицу копии приложения приходилось включить в схемы всех филиалов. С моделью разрешений вызывающего такая необходимость отпадает. Теперь весь код можно разместить в едином централизованном хранилище. И когда пользователь из Северного филиала вызовет централизованно хранящуюся программу (возможно, воспользовавшись синонимом), он автоматически получит доступ к таблицам соответствующей схемы.

 

Модель разрешений вызывающего

Рис. 3. Модель разрешений вызывающего

 

Как видите, идея модели разрешений вызывающего проста. Давайте посмотрим, как она реализуется программно, а затем разберемся в том, как ее лучше использовать.

 

Синтаксис модели разрешений вызывающего

Синтаксис поддержки разрешений вызывающего очень прост. В заголовок программы, перед ключевым словом IS или AS, включается следующая конструкция:

AUTHID CURRENT_USER

В качестве примера рассмотрим все ту же процедуру «exec DDL», но на этот раз объ­явленную с разрешениями вызывающего:


PROCEDURE execddl (ddl_in in VARCHAR2)
   AUTHID CURRENT_USER
IS
BEGIN
   EXECUTE IMMEDIATE ddl_in;
END;

Секция AUTHID CURRENT_USER перед ключевым словом IS указывает, что при выполнении процедуры execDDL должны использоваться привилегии вызывающего или текущего пользователя, но не привилегии ее создателя. Если не включить в программу секцию AUTHID или задать в ней параметр AUTHID DEFINER, разрешение ссылок будет выполняться в соответствии с привилегиями схемы-владельца программы.

 

РАЗРЕШЕНИЯ ВЫЗЫВАЮЩЕГО ДЛЯ ДИНАМИЧЕСКОГО SQL

 

Ограничения на использование модели разрешений вызывающего

При использовании модели разрешений вызывающего необходимо помнить о некоторых правилах и ограничениях:

  •  По умолчанию в программах действует режим AUTHID DEFINER.
  •  В случае применения любых SQL-ссылок на объекты базы данных модель разрешений вызывающего требует проверки во время выполнения программы привилегий, предоставленных вызывающему.
  •  При использовании модели разрешений вызывающего роли действуют во время выполнения программы, если только программа с разрешениями вызывающего не была вызвана из программы с разрешениями создателя.
  •  Секция AUTHID может содержаться только в заголовках отдельных подпрограмм (процедур или функций), в спецификации пакета или объектного типа. Она не может задаваться в отдельных программах пакета или методах объектного типа. Таким образом, весь пакет работает с правами вызывающего или весь пакет рабо­тает с правами создателя. Если одна часть пакета должна выполняться с правами вызывающего, а другая — с правами создателя, значит, придется создать два пакета.
  •  Разрешение внешних ссылок с привилегиями вызывающего будет действовать для следующих видов команд:
  • SELECT, INSERT, UPDATE, MERGE и DELETE;
  • команды управления транзакциями LOCK TABLE;
  • команд управления курсорами OPEN и OPEN FOR;
  • команд динамического SQL execute immediate и open for using;
  • команд SQL, обработанных процедурой DBMS_SQL.PARSE.
  •  Для разрешения всех внешних ссылок на программы PL/SQL и методы объектных типов во время компиляции всегда используются привилегии создателя.
  •  Привилегии вызывающего можно использовать для изменения разрешения ссылок на статические элементы данных (таблицы и представления). Привилегии вызывающего могут использоваться для разрешения внешних ссылок на программы PL/SQL. Пример:
EXECUTE IMMEDIATE 'BEGIN программа; END;';

В этой команде ссылка программа будет разрешена во время выполнения в соответствии с привилегиями и пространством имен вызывающего. Также вместо анонимного блока можно использовать команду SQL CALL. (Непосредственно в PL/SQL ее применять нельзя, поскольку она здесь не поддерживается.)

 

Комбинированная модель разрешений

Как вы думаете, что произойдет, если программа с разрешениями создателя вызовет программу с разрешениями вызывающего? А если наоборот? Правила просты:

  •  Если программа с разрешениями создателя вызывает программу с разрешениями вызывающего, то при выполнении такой программы будут действовать привилегии вызывающей программы.
  •  Если программа с разрешениями вызывающего вызывает программу с разрешениями создателя, то при выполнении такой программы будут действовать привилегии ее владельца. Когда управление будет возвращено вызывающей программе, возобновится действие разрешений вызывающего.

Просто запомните, что разрешения создателя «сильнее» разрешений вызывающего.

На сайте книги доступны файлы, при помощи которых можно исследовать нюансы модели прав вызывающего:

  •  invdefinv.sql и invdefinv.tst — два сценария, демонстрирующих приоритет прав создателя перед правами вызывающего.
  •  invdef_overhead.tst — анализ дополнительных затрат при использовании прав вызывающего (подсказка: разрешение во время выполнения работает медленнее разрешения во время компиляции).
  •  invrole.sql — демонстрация того, как изменения в ролях могут влиять на разрешение объектных ссылок во время выполнения.
  •  irdynsql.sql — анализ некоторых сложностей, связанных с использованием прав создателя и вызывающего в динамическом SQL.

 

Назначение ролей программам PL/SQL (Oracle Database 12c)

До выхода Oracle Database 12c программа с правами создателя (определенная с AUTHID DEFINER или AUTHID) всегда выполнялась с привилегиями стороны, определившей программу. Программа с правами вызывающего (с AUTHID CURRENT_USER) всегда выполнялась с привилегиями стороны, вызвавшей программу.

Из существования двух разных режимов AUTHID следовало, что любая программа, предназначенная для выполнения всеми пользователями, должна была определяться с правами создателя. Затем она выполнялась со всеми привилегиями создателя, что могло оказаться неоптимальным с точки зрения безопасности.

В Oracle Database 12c появилась возможность назначения ролей пакетам PL/SQL и процедурам /функциям уровня схемы. Привилегии программ на базе ролей позволяют разработчику оптимизировать привилегии, доступные для стороны, вызвавшей программу. Теперь программу можно определить с правами вызывающего, а затем дополнить привилегии вызывающего более конкретными и ограниченными привилегиями, предоставляемыми ролью. Следующий пример показывает, как назначать роли программам и как они влияют на выполнение программ. Предположим, схема HR содержит таблицы employees и departments, которые определяются и заполняются данными:

CREATE TABLE departments(
   department_id     INTEGER,
   department_name   VARCHAR2 (100),
   staff_freeze      CHAR (1)
)
/
BEGIN
   INSERT INTO departments
      VALUES (10, 'IT', 'Y');
   INSERT INTO departments
        VALUES (20, 'HR', 'N');
   COMMIT;
END;
/
CREATE TABLE employees
(
  employee_id     INTEGER,
  department_id   INTEGER,
   last_name       VARCHAR2 (100)
)
/
BEGIN
   DELETE FROM employees;
   INSERT INTO employees VALUES (100, 10, 'Price');
   INSERT INTO employees VALUES (101, 20, 'Sam');
   INSERT INTO employees VALUES (102, 20, 'Joseph');
   INSERT INTO employees VALUES (103, 20, 'Smith');
   COMMIT;
END;
/

Схема SCOTT содержит только таблицу employees:

CREATE TABLE employees
(   employee_id     INTEGER,
  department_id   INTEGER,
   last_name       VARCHAR2 (100)
)
/
BEGIN
   DELETE FROM employees;
   INSERT INTO employees VALUES (100, 10, 'Price');
   INSERT INTO employees VALUES (101, 20, 'Sam');
   INSERT INTO employees VALUES (102, 20, 'Joseph');
   INSERT INTO employees VALUES (103, 20, 'Smith');
   COMMIT;
END;
/

Схема HR также содержит процедуру для удаления всех работников заданного отдела при условии, что штат отдела не «заморожен». Сначала я определю эту процедуру с правами создателя:

CREATE OR REPLACE PROCEDURE remove_emps_in_dept (
   department_id_in IN employees.department_id%TYPE)
   AUTHID DEFINER
IS
   l_freeze   departments.staff_freeze%TYPE;
BEGIN
   SELECT staff_freeze
     INTO l_freeze
     FROM HR.departments
    WHERE department_id = department_id_in;
   IF l_freeze = 'N'
    THEN
       DELETE FROM employees
             WHERE department_id =
                      department_id_in;
    END IF;
 END;
 /

Схеме SCOTT разрешается выполнение этой процедуры:

GRANT EXECUTE
   ON remove_emps_in_dept
  TO SCOTT
/

Когда SCOTT выполняет процедуру так, как показано ниже, удаляются три строки — но из таблицы employees схемы HR, поскольку процедура объявлена с правами создателя:

BEGIN
   HR.remove_emps_in_dept (20);
END;
/

Процедуру нужно изменить так, чтобы строки удалялись из таблицы employees схемы SCOTT, а не HR. Именно это и делает модель прав создателя. Но если привести секцию AUTHID процедуры к виду:

AUTHID CURRENT_USER

и снова выполнить процедуру, будет получен следующий результат:

BEGIN * ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "HR.REMOVE_EMPS_IN_DEPT", line 7
ORA-06512: at line 2

Проблема в том, что Oracle теперь использует привилегии SCOTT для разрешения ссылок на две таблицы: HR.departments и HR.employees. Однако SCOTT не имеет привилегий для таблицы departments схемы HR, поэтому Oracle выдает ошибку ORA-00942. До выхода Oracle Database 12c администратор базы данных должен был предоставить SCOTT необходимые привилегии HR. departments.  Теперь вместо этого можно выполнить следующие действия:

  1. В схеме с необходимыми привилегиями создайте роль и предоставьте ее hr:
CREATE ROLE hr_departments
/
GRANT hr_departments TO hr
/

      2. Подключитесь к hr, предоставьте нужные привилегии роли и назначьте ее про­цедуре:

GRANT SELECT
   ON departments
   TO hr_departments
/
GRANT hr_departments TO PROCEDURE remove_emps_in_dept
/

Теперь при выполнении следующего фрагмента из схемы SCOTT строки будут удаляться правильно:

SELECT COUNT (*)
  FROM employees
 WHERE department_id = 20
/

  COUNT(*)
----------
         3

BEGIN
   hr.remove_emps_in_dept (20);
END;
/

SELECT COUNT (*)
  FROM employees
 WHERE department_id = 20
/

  COUNT(*)
----------
         0

Роли, назначаемые программам, не влияют на компиляцию. Они влияют на проверку привилегий команд SQL, выдаваемых программой во время выполнения. Процедура или функция выполняется с привилегиями обеих своих ролей, а также других активных ролей. Эта возможность в основном используется для программ с правами вызывающего, как в приведенном примере. Скорее всего, для программ с правами создателя возможность назначения ролей будет рассматриваться при выполнении динамического SQL, поскольку привилегии таких динамических команд проверяются во время выполнения.

 

Функции «Кто меня вызвал?» (Oracle Database 12c)

В Oracle Database 12c появились две новые функции (которые могут вызываться только из команд SQL), которые возвращают информацию о вызывающем пользователе в зависимости от того, используется ли модель прав вызывающего или создателя:

  •  ORA_INVOKING_USER — возвращает имя пользователя, активизирующего текущую команду или представление. Все промежуточные представления рассматриваются в соответствии с их секциями BEQUEATH. Если вызывающий пользователь является пользователем, определяемым Oracle Database Real Application Security (еще одна новая возможность 12.1, следующее поколение функциональности виртуальных приватных баз данных), то функция возвращает XS$NULL.
  •  ORA_INVOKING_USERID — возвращает идентификатор пользователя, активизирующего текущую команду или представление. Все промежуточные представления рассматриваются в соответствии с их секциями BEQUEATH. Если вызывающий пользователь является пользователем, определяемым Oracle Database Real Application Security (еще одна новая возможность 12.1, следующее поколение функциональности виртуальных приватных баз данных), то функция возвращает идентификатор, общий для всех сеансов Real Application Security, но отличный от идентификатора любого пользователя базы данных.

Примеры использования этих функций продемонстрированы в следующем разделе, при описании секции BEQUEATH CURRENT_USER для представлений.

 

BEQUEATH CURRENT_USER для представлений (Oracle Database 12c)

До выхода версии Oracle Database 12c функции, выполняемые представлениями, всегда выполнялись с привилегиями владельца представления, а не владельца функции. Таким образом, если функция определялась с моделью прав вызывающего, ее поведение могло сильно отличаться от ожидаемого.

В версии 12c добавилась секция BEQUEATH для представлений, которая позволяет определить представление, адаптирующееся к задействованным в нем функциям с правами вызывающего.

Рассмотрим пример использования этой возможности (весь код, приведенный в этом разделе, находится в файле 12c_bequeath.sql на сайте книги). Я создаю таблицу и функцию в схеме HR:

CREATE TABLE c12_emps
(
   employee_id     INTEGER,
   department_id   INTEGER,
   last_name       VARCHAR2 (100)
)
/

BEGIN
   INSERT INTO c12_emps VALUES (1, 100, 'abc');
   INSERT INTO c12_emps VALUES (2, 100, 'def');
   INSERT INTO c12_emps VALUES (3, 200, '123');
   COMMIT;
END;
/

CREATE OR REPLACE FUNCTION emps_count (
   department_id_in IN INTEGER)
   RETURN PLS_INTEGER
   AUTHID CURRENT_USER
IS
   l_count    PLS_INTEGER;
   l_user     VARCHAR2 (100);
   l_userid   VARCHAR2 (100);
BEGIN
   SELECT COUNT (*)
     INTO l_count
     FROM c12_emps
    WHERE department_id = department_id_in;

   /* Вывести информацию о вызывающем пользователе */
   SELECT ora_invoking_user, ora_invoking_userid
     INTO l_user, l_userid FROM DUAL;

   DBMS_OUTPUT.put_line ('Invoking user=' || l_user);
   DBMS_OUTPUT.put_line ('Invoking userID=' || l_userid);

   RETURN l_count;
END;
/

Обратите внимание на вызовы двух новых функций: ORA_INVOKING_USER и ORA_INVOKING_ USER_ID.

Затем я создаю представление, указывая права вызывающего в BEQUEATH, и обеспечиваю возможность обращения с запросом к этому представлению для SCOTT:

CREATE OR REPLACE VIEW emp_counts_v
   BEQUEATH CURRENT_USER
AS
   SELECT department_id, emps_count (department_id) emps_in_dept
     FROM c12_emps
/

GRANT SELECT ON emp_counts_v TO scott
/

В схеме SCOTT создается еще одна таблица cl2_emps, которая заполняется другими данными:

CREATE TABLE c12_emps
(
   employee_id     INTEGER,
   department_id   INTEGER,
   last_name       VARCHAR2 (100)
)
/

BEGIN
   INSERT INTO c12_emps VALUES (1, 200, 'SCOTT.ABC');
   INSERT INTO c12_emps VALUES (2, 200, 'SCOTT.DEF');
   INSERT INTO c12_emps VALUES (3, 400, 'SCOTT.123');
   COMMIT;
END;
/

Наконец, я выполняю выборку всех строк представления. Результат запроса:

SQL> SELECT * FROM hr.emp_counts_v
  2  /

DEPARTMENT_ID EMPS_IN_DEPT
------------- ------------
          100            0
          100            0
          200            2

SCOTT
107
SCOTT
107
SCOTT
107

Как видите, данные, возвращенные представлением, взяты из таблицы HR (идентифи­катор отдела 100), но сводная информация, возвращаемая вызовом функции, отражает содержимое таблицы scott, а функции ora_invoking* возвращают информацию scott.

Учтите, что конструкция BEQUEATH CURRENT_USER не превращает само представление в объект с правами вызывающего. Разрешение имен в представлении по-прежнему осуществляется с использованием схемы владельца представления, а привилегии проверяются с использованием привилегий владельца представления.

Главное преимущество этого синтаксиса заключается в том, что он позволяет таким функциям, как SYS_CONTEXT и USERENV, возвращать логически целостные результаты при вызове из представлений.

 

Ограничение привилегий в модели прав вызывающего (Oracle Database 12c)

Когда пользователь запускает процедуру или функцию, определенную в программной единице PL/SQL, которая была создана с секцией AUTHID CURRENTJJSER, эта подпрограмма временно наследует все привилегии вызывающего пользователя во время выполнения процедуры. Соответственно, в это время владелец программы с правами вызывающего получает доступ к привилегиям вызывающего пользователя.

Если привилегии вызывающего превосходят привилегии владельца, возникает риск того, что владелец подпрограммы сможет злоупотребить повышенными привилегиями вызывающего. Риски такого рода повышаются, когда пользователи приложений получают доступ к базе данных, использующей процедуры с правами вызывающего.

В Oracle Database 12c добавлены две новые привилегии, которые могут управлять доступностью привилегий вызывающего для процедуры владельца: INHERIT PRIVILEGES и INHERIT ANY PRIVILEGES.

Любой пользователь может предоставить или отозвать привилегию INHERIT PRIVILEGES для пользователей, процедуры которых с правами вызывающего он хочет запускать. Привилегия INHERIT ANY PRIVILEGES находится под управлением пользователей SYS.

Когда пользователь запускает процедуру с правами вызывающего, Oracle проверяет, имеется ли у владельца процедуры привилегия INHERIT PRIVILEGES для вызывающего пользователя или же владельцу была предоставлена привилегия INHERIT ANY PRIVILEGES. Если проверка привилегий не проходит, Oracle возвращает ошибку ORA-06598 (недостаточный уровень inherit privileges).

Преимущество этих двух привилегий заключается в том, что они позволяют вызывающему пользователю контролировать доступ к их привилегиям при запуске процедур с правами вызывающего или запросов к представлениям BEQUEATH CURRENT_USER.

Всем пользователям по умолчанию предоставляется привилегия INHERIT PRIVILEGES ON USER новый пользователь TO PUBLIC при создании их учетных записей (или обновлении ранее созданных учетных записей до текущей версии). Это означает, что если в вашей системе не существует риска злоупотребления привилегиями «сильных вызывающих» со стороны «слабых владельцев», все будет работать точно так же, как работало в более ранних версиях Oracle Database.

Вызывающий пользователь может лишить других пользователей привилегии INHERIT PRIVILEGES и предоставить ее только доверенным пользователям. Синтаксис предоставления привилегии INHERIT PRIVILEGES выглядит так:

GRANT INHERIT PRIVILEGES ON USER вызывающий_пользователь TO владелец_процедуры

Теперь настало время поговорить об условной компиляции в Oracle и как это влияет на техники программирования в PL/SQL.

 

Вас заинтересует / Intresting for you:

Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 4654 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 14850 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Тип данных RAW в PL/SQL
Тип данных RAW в PL/SQL 12356 просмотров Doctor Thu, 12 Jul 2018, 08:41:33
Символьные функции и аргументы...
Символьные функции и аргументы... 18596 просмотров Анатолий Wed, 23 May 2018, 18:54:01
Войдите чтобы комментировать

OraCool аватар
OraCool ответил в теме #9512 4 года 6 мес. назад
Используйте модель разрешений создателя для достижения максимальной произво­дительности, а также упрощения управления и контроля за привилегиями доступа к таблицам баз данных. Модель разрешений вызывающего применяется только для решения конкретных проблем (например, программ, использующих динамический SQL с созданием или уничтожением объектов баз данных).