Как мне скрыть свою таблицу Oracle?

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

У меня есть пользователь/схема 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, тем самым сводя на нет цель этого упражнения, поскольку я хочу, чтобы этот случай выдавал ошибку.

К вам...


person VinceJS    schedule 27.09.2011    source источник


Ответы (4)


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

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

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

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


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

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

person APC    schedule 27.09.2011
comment
Это именно то, что я сделал, внедрил проверку кода, автоматическое сканирование исходного кода и обучение разработчиков. Но я хочу быть абсолютно уверенным в фазе FAT. И это можно сделать сложным путем с помощью exp/imp (или expdp/impdp) с предложениями fromuser= touser=. Я пытался избежать этого, но это кажется единственным выходом... - person VinceJS; 27.09.2011
comment
+1, за просмотры и синонимы. Моя компания установила то же самое, и это работает. Это применимо только в том случае, если вы отмените выбор из общедоступных, чтобы разработчики не могли писать select * from xyz.blah. Простая работа на user_privileges избавит от них. Любой код, который не соответствует стандарту, не работает. - person Ben; 28.09.2011
comment
@VinceJS, зачем экспортировать/импортировать? изменить таблицу... переименовать - person llayland; 28.09.2011
comment
Да, можно использовать изменение переименования таблицы, но это становится немного утомительным, если их больше нескольких. Я собирался переименовать схему, чтобы скрыть ее, но Oracle не позволяет этого, поэтому единственный способ сделать это — использовать exp/imp (или expdp/impdp) с предложениями fromuser= touser= (и сделать несколько исправлений, потому что imp если далеко не идеально!) - person VinceJS; 28.09.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. Каждые несколько минут, вероятно, излишни для хорошо написанной системы, вам просто нужно убедиться, что она запускается чаще, чем запросы устаревают из общего пула. Если у вас есть приложение, которое не использует переменные связывания должным образом, это может потребоваться каждые несколько минут, чтобы ничего не пропустить.

person Justin Cave    schedule 27.09.2011
comment
Это хороший способ проверить, что приложение не использует полные имена, спасибо! - person VinceJS; 28.09.2011

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

         ALTER SESSION SET CURRENT_SCHEMA = schema

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

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

           select * from X.tableName

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

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

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

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

П.П.С. Поскольку вы подробно изложили свои требования:

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

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

Ваши лучшие шансы на успех в размещении этого интеллекта в серверной части будут состоять в том, чтобы отозвать все прямые права на таблицы и представления и потребовать, чтобы клиентские приложения обращались к объектам через хранимые процедуры, потому что механизм базы данных сам по себе не знает о таких вещах, как выпуск приложения. уровни. Я не вижу чисто ДЕКЛАРАТИВНОГО способа сделать это. В значительной степени это должно быть процедурным. Ваша собственная внутренняя логика должна была бы взять на себя ответственность за арбитраж между объектами с одним и тем же именем в разных схемах. Тем не менее, такие функции, как триггеры AFTER LOGON и ALTER SCHEMA, должны оказаться полезными для вас.

person Tim    schedule 27.09.2011
comment
Важно, чтобы клиентский код получал ошибку при использовании имени схемы, поскольку оно может не совпадать с тем, что указано разработчиком. Например, таблица может быть синонимом, использующим ссылку на базу данных, или таблица может размещаться в нескольких схемах, каждая из которых предназначена для разных выпусков. Базе данных следует предоставить разрешение фактического местоположения объекта, на который ссылается клиентское приложение, а не клиентское приложение, иначе вы потеряете гибкость развертывания. - person VinceJS; 27.09.2011

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

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

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

person Bart K    schedule 27.09.2011