Как мне спрятать мою таблицу Oracle? - PullRequest
6 голосов
/ 27 сентября 2011

Вот сценарий (упрощенный пример):

У меня есть пользователь / схема Oracle под названием ABC. ABC владеет таблицей TRN. Код на стороне клиента подключается к базе данных как ABC и выбирает из ABC.TRN.

Пока все хорошо. Однако я не хочу, чтобы клиентский код указывал имя схемы Oracle. Теперь я думаю, что удалил все ссылки в клиентском коде, которые ссылаются на схему, но я хочу проверить это, чтобы убедиться.

Итак, я хочу создать нового пользователя / схему с именем DEF, которая будет использоваться клиентом для подключения к базе данных. Когда клиентское приложение выбирает из ABC.TRN, оно должно выдавать ошибку. Однако, если клиентское приложение выбирает из TRN (без имени схемы), оно должно вернуть данные.

Есть ли способ сделать это? Обратите внимание, что DEF должен находиться в той же базе данных, что и ABC, есть только одна таблица TRN таблицы (принадлежит ABC), и я не могу использовать ссылки на базу данных.

Я попытался создать нового пользователя XYZ с синонимом, указывающим на ABC.TRN и дать ему право выбора на ABC.TRN. Затем я создал пользователя DEF с синонимом, указывающим на XYZ.TRN, и дал DEF право выбора для XYZ.TRN. Это работает, но Oracle достаточно умен, чтобы знать, что если у DEF есть права на выбор из XYZ.TRN, то у него также есть права на выбор из ABC.TRN, тем самым побеждая цель этого упражнения, так как я хочу, чтобы этот случай выдал ошибку.

За вами ...

Ответы [ 4 ]

7 голосов
/ 27 сентября 2011

Нет простого способа сделать это.

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

Архитектурный подход будет аналогичен структуре трех ваших схем, но с тонким поворотом: схема посередине использует представления. Итак, схема ABC владеет таблицами и предоставляет им разрешения для схемы XYZ. Схема XYZ создает простые представления для этих таблиц (SELECT *, без предложений WHERE) и предоставляет разрешения для представлений для схемы DEF. Схема DEF может выбирать только объекты XYZ.

Конечно, все эти усилия не помешают разработчикам кодировать SELECT * FROM xyz.whatever. В этом случае я отсылаю вас к моему первому предложению 8 -)


На самом деле есть один, действительно очень злой способ сделать это. Используйте синонимы в схеме, обращенной к приложению (DEF), а затем измените имя схемы, владеющей данными (ABC).

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

5 голосов
/ 27 сентября 2011

Вам действительно нужно выдать ошибку? Или вам просто нужно убедиться, что приложение не использует полностью определенные имена (например, ABC.TRN)?

Предполагая, что вы просто заинтересованы в проверке того, что приложение не использует полностью определенные имена и что выдача ошибки была просто механизмом, о котором вы думали уведомить вас, вы, вероятно, можете проверить код, запросив V$SQL, пока приложение работает. V$SQL перечисляет все операторы SQL в общем пуле в Oracle. Если вы регулярно запрашиваете эту таблицу во время работы приложения, вы увидите все SQL-выражения, которые оно выдает. Затем вы можете регистрировать любые операторы, которые используют полностью определенные имена.

Например

CREATE OR PROCEDURE look_for_abc_trn
AS
BEGIN
  FOR x IN (SELECT *
              FROM v$sql
             WHERE upper(sql_fulltext) LIKE '%ABC.TRN%')
  LOOP
    INSERT INTO log_of_bad_sql( sql_fulltext, <<other columns>> )
      VALUES( x.sql_fulltext, <<other columns>> );
  END LOOP;
END;

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

1 голос
/ 27 сентября 2011

Как насчет ALTER SESSION?

         ALTER SESSION SET CURRENT_SCHEMA = schema

Это позволит вам войти в систему как пользователь, которому предоставлены права выбора для таблицы, принадлежащей схеме X, и выполнить SP, который изменяетсеанс к схеме X. Внешний код не будет знать, что это произошло.

Однако, если ваш внешний код задает схему X:

           select * from X.tableName

Я не думаю,это вызовет ошибку.

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

Возможно ли создать новую схемупередать владелец объектов старой схемы, а затем удалить старую схему и затем использовать подход, описанный выше?

PS См. триггеры ПОСЛЕ ВХОДА: http://psoug.org/reference/system_trigger.html

PPS Поскольку вы разработалиВаши требования:

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

Если местоположение объекта находится не в CURRENT_SCHEMA, а в какой-то другой схеме, обе из которыхслучается, что есть таблицы с именем CUSTOMER, например, ядро ​​СУБД не будет знать, что оператор, отправленный ему клиентским приложением, должен ссылаться на другую схему, если имя таблицы не настолько квалифицированно.Это подразумевает уровень мета-знаний, которых нет у движка, хотя он предоставляет разработчику инструменты для создания такого интеллекта в форме хранимых процедур и триггеров и предоставления / отзыва контроля над объектами.

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

0 голосов
/ 27 сентября 2011

Вы не можете сделать это.Синонимы - это не что иное, как указатели на объекты других схем.Вы предоставляете доступ к реальному объекту, а не к синониму.Из документов Oracle:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/views003.htm

Сами синонимы не подлежат защите.Когда вы предоставляете объектные привилегии для синонима, вы действительно предоставляете привилегии для базового объекта, и синоним действует только как псевдоним для объекта в инструкции GRANT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...