ПРЕДСТАВЛЕНИЯ И БЕЗОПАСНОСТЬ

 

Чтобы проиллюстрировать использование представлений для целей безопасности, приведем ряд примеров, основанных (по большей части) опять-таки на базе данных поставщиков и деталей.

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

CREATE VIEW ПАРИЖСКИЕ_ПОСТАВЩИКИ

AS SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ,

СОСТОЯНИЕ, ГОРОД

FROM S

WHERE ГОРОД = 'Париж';

Пользователи этого представления видят «горизонтальное подмножество» (или, точнее, подмножество строк, подмножество, зависящее от значений) базовой таблицы S.

2. Пользователю разрешен доступ ко всем записям поставщиков, но не к рейтингам поставщиков (значение поля СОСТОЯНИЕ):

CREATE VIEW СКРЫТОЕ_СОСТОЯНИЕ

AS SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ,

ГОРОД

FROM S;

Пользователи этого представления видят «вертикальное подмножество» (или, точнее, подмножество столбцов, независимое от значений) подмножество базовой таблицы S.

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

CREATE VIEW ПАРИЖСКИЕ_БЕЗ_РЕЙТИНГОВ

AS SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, ГОРОД

FROM S

WHERE ГОРОД = 'Париж';

Пользователи этого представления видят подмножество строк и столбцов базовой таблицы S.

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

CREATE VIEW МОИ_ТАБЛИЦЫ

AS SELECT *

FROM SYSIBM.SYSTABLES

WHERE CREATOR = USER;

Ключевое слово USER(пользователь) обозначает системную переменную, значение которой представляет собой ИД санкционирования. Оно может входить во фразу SELECT, во фразу WHERE, во фразу SET предложения UPDATE, либо как вставляемое значение — в предложение INSERT. Идентификатор санкционирования в запросе — это ИД санкционирования для пользователя, исполняющего фразы SELECT или WHERE (либо предложения UPDATE или INSERT), в которые он входит. В приведенном примере, следовательно, он представляет не ИД пользователя, который создает это представление, а ИД пользователя, который использует это представление. Если, например, пользователь xyz издает предложение:

SELECT *

FROM МОИ_ТАБЛИЦЫ;

то DB2, а фактически генератор планов прикладных задач, по существу, преобразует это предложение в следующее:

SELECT *

FROM SYSIBM.SYSTABLES

WHERE CREATOR = 'xyz';

Аналогично представлению из приведенного выше первого примера, это представление является «горизонтальным подмножеством» лежащей в основе базовой таблицы. Однако в данном примере различные пользователи видят здесь различные подмножества. Фактически эти подмножества не пересекаются ни для каких двух пользователей. Такие подмножества иногда называются контекстно-зависимыми.

5. Пользователю разрешен доступ к средним объемам поставок по поставщикам, но не к каким-либо индивидуальным объемам поставок:

CREATE VIEW AVG (НОМЕР_ПОСТАВЩИКА, СРЕДНИЙ_ОБЪЕМ)

AS SELECT НОМЕР_ПОСТАВЩИКА, AVG (КОЛИЧЕСТВО)

FROM SP

GROUP BY НОМЕР_ПОСТАВЩИКА;

Пользователи этого представления видят статистическую сводку лежащей в основе базовой таблицы S.

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

Как показывают приведенные примеры, механизм представлений системы DB2 «задаром» обеспечивает очень важные средства безопасности — «задаром» во всяком случае потому, что механизм представлений включен в систему для иных целей, как указывалось в главе 8. Более того, многие проверки полномочий доступа, даже проверки, зависимые от значений, могут осуществляться на стадии компиляции (во время связывания), а не на стадии исполнения, что обеспечивает существенный выигрыш производительности. Однако подход к безопасности, основанный на представлениях, иногда оказывается несколько тяжеловесным, в частности, если некоторому конкретному пользователю необходимы различные привилегии доступа к различным подмножествам одной и той же таблицы в одно и то же время. Рассмотрим следующий пример. Предположим, что данному пользователю разрешена выборка (операция SELECT) рейтингов, т. е. значений состояния, для всех поставщиков, а обновлять их (операция UPDATE) разрешается только для поставщиков из Парижа. Тогда потребуется два следующих представления:

CREATE VIEW ВСЕ_РЕЙТИНГИ CREATE VIEW ПАРИЖСКИЕ_ РЕЙТИНГИ
AS SELECT НОМЕР_ ПОСТАВЩИКА, СОСТОЯНИЕ AS   SELECT НОМЕР_ ПОСТАВЩИКА, СОСТОЯНИЕ
  FROM S;   FROM S
        WHERE ГОРОД=' ПАРИЖ';

При этом операции SELECT могут быть адресованы представлению ВСЕ_РЕЙТИНГИ, а операции обновления — только представлению ПАРИЖСКИЕ_РЕЙТИНГИ. В связи с этим программирование становится довольно невразумительным. В этом можно, например, убедиться, рассматривая структуру программы, которая просматривает и печатает рейтинги всех поставщиков, а также обновляет некоторые из них (рейтинги поставщиков из Парижа), когда это требуется.

Другой недостаток связан с тем, что при вставке (операция INSERT) или обновлении (операция UPDATE) записей при помощи представления система DB2 не требует, чтобы новая или обновленная запись удовлетворяла предикату, определяющему это представление. Такое требование можно ввести с помощью спецификации CHECK, но эта возможность, как пояснялось в главе 8, не всегда может быть использована и во всяком случае это факультативная возможность — пользователь не обязан ее специфицировать. Таким образом, приведенное выше представление ПАРИЖСКИЕ_ПОСТАВЩИКИ, например, может не дать пользователю возможности видеть поставщиков, которые находятся не в Париже, но при отсутствии спецификации CHECK оно не может помешать пользователю создать такого поставщика или переместить какого-либо существующего парижского поставщика в некоторый другой город. Такая операция, конечно, приведет к тому, что новая или обновленная запись немедленно исчезнет из этого представления, но она однако же появится в соответствующей базовой таблице.