Ограничения на основе существующих атрибутов — КиберПедия 

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Ограничения на основе существующих атрибутов

2019-08-04 115
Ограничения на основе существующих атрибутов 0.00 из 5.00 0 оценок
Заказать работу

Если правила корпоративной политики выражаются в терминах предметной области, то можно сформировать соответствующий предикат безопасности в терминах данных, хранимых в СУБД.

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

младшие финансовые аналитики имеют право чтения отчетов старше шести месяцев;

старшие финансовые аналитики имеют право чтения отчетов старше одного месяца;

всем остальным сотрудникам доступ к документам запрещен.

В таком случае можно построить примерно такой предикат:

(IsUserInRole('senior_analyst') and ReportDate < DateAdd(month, GetDate(), 1))  OR (IsUserInRole('junior_analyst') and ReportDate < DateAdd(month, GetDate(), 6))

В принципе, тот же самый результат можно получить и другими способами. Например, вот такое выражение SQL отражает те же самые правила:

case  when ReportDate > DateAdd(month, GetDate(), 1) then false  when ReportDate > DateAdd(month, GetDate(), 6) then IsUserInRole('senior_analyst')  else IsUserInRole('junior_analyst') end

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

(IsUserInRole(<role1>) AND <role1_restrictions>)  OR (IsUserInRole(<role2>) AND <role2_restrictions>)  OR... (IsUserInRole(<roleN>) AND <roleN_restrictions>)

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

Лишение доступа

Форма предиката безопасности, рассмотренная выше, подразумевает «пессимистичный» режим, т.е. доступ к данным имеют только те категории пользователей, которые явно перечислены в предикате.

ПРИМЕЧАНИЕ Строго говоря, если мы не опишем ни одного правила, то предикат будет пустым и доступ получат все пользователи. Однако выдача таким способом доступа хотя бы одной роли автоматически лишит доступа всех остальных пользователей. Решить эту проблему можно раз и навсегда - введя дополнительный член...OR FALSE в предикат безопасности. Однако подобный вырожденный случай нетрудно обработать специальным образом, и далее в тексте везде предполагается наличие в списке доступа хотя бы одного явного разрешения.

Иногда удобнее описывать правила безопасности в терминах «оптимистичного» режима, т.е. лишить доступа только некоторое множество пользователей. В этом случае предикат приобретет такой вид:

NOT (  (IsUserInRole(<restricted_role1>) [AND <restricted_role1_restrictions>]) OR...  (IsUserInRole(<restricted_roleN>) [AND <restricted_roleN_restrictions>]) )

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

Соединив эти два подхода, мы получим возможность как «карать», так и «миловать» пользователей:

(-- секция разрешений  (IsUserInRole(<role1>) AND <role1_restrictions>) OR...  (IsUserInRole(<roleN>) AND <roleN_restrictions>) ) AND NOT (-- секция запретов  (IsUserInRole(<restricted_role1>) [AND <restricted_role1_restrictions>]) OR...  (IsUserInRole(<restricted_roleN>) [AND <restricted_roleN_restrictions>]) )

Такой принцип защиты очень похож на используемый в Windows NT.

Рассмотрим варианты применения данной техники на примере базы данных Northwind, которая входит в поставку MS SQL Server.

Локальные атрибуты

В простейшем случае предикаты для всех ролей зависят только от значений полей защищаемой записи. Рассмотрим таблицу Orders (несущественные для рассматриваемой задачи ограничения пропущены):

CREATE TABLE Orders (  OrderID int IDENTITY(1, 1) NOT NULL,  CustomerID nchar(5) NULL,  EmployeeID int NULL,  OrderDate datetime NULL,  RequiredDate datetime NULL,  ShippedDate datetime NULL,  ShipVia int NULL,  Freight money NULL CONSTRAINT DF_Orders_Freight DEFAULT(0),  ShipName nvarchar(40) NULL,  ShipAddress nvarchar(60) NULL,  ShipCity nvarchar(15) NULL,  ShipRegion nvarchar(15) NULL,  ShipPostalCode nvarchar(10) NULL,  ShipCountry nvarchar(15) NULL,  CONSTRAINT FK_Orders_Employees FOREIGN KEY (EmployeeID) REFERENCES Employees (EmployeeID) )

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

Менеджеры по продажам (роль ‘Sales Representative’) имеют право просматривать только «свои» заказы и не могут видеть заказы, введенные другими менеджерами по продажам.

Директор по продажам (роль ‘Vice President, Sales’) имеет право просматривать любые заказы.

Все остальные сотрудники доступа к заказам не имеют.

Этим правилам соответствует вот такое представление:

CREATE VIEW [Secure Orders] AS  SELECT * FROM Orders where (IsUserInRole('Sales Representative') AND EmployeeID = CurrentEmployeeID()) OR (IsUserInRole('Vice President, Sales') AND TRUE)

Здесь подразумевается, что функция CurrentEmployeeID() неким «магическим» образом возвращает идентификатор сотрудника, соответствующий пользователю, от имени которого произведено подключение. Реализация этой функции, как и функции IsUserInRole(), зависит от используемой СУБД. Обратите внимание на вторую часть предиката: для директора по продажам никаких дополнительных ограничений не предусмотрено, но для общности мы использовали выражение TRUE для представления этого факта. При подготовке предиката вручную фрагмент AND TRUE можно опустить, хотя оптимизаторы, используемые в современных СУБД, достаточно интеллектуальны, чтобы выбросить избыточные выражения из плана запроса.

СОВЕТ Иногда предикат безопасности может оказаться настолько сложным, что оптимизатор СУБД не сможет самостоятельно построить оптимальный план выполнения запроса. В таких случаях может потребоваться ручное преобразование выражения предиката в более адекватную форму. Пока что мы будем считать, что оптимизатор идеален, и все выражения будут представлены в наиболее удобном для чтения виде.

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

(IsUserInRole('Sales Representative') AND EmployeeID = CurrentEmployeeID())  OR (IsUserInRole('Vice President, Sales') AND TRUE)  OR (IsUserInRole('Everyone') AND ShippedDate < DateAdd(month, -6, GetDate())

Стоит обратить внимание на две особенности предиката:

Во-первых, (опять же из соображений общности) в дополнительном условии проверяется принадлежность текущего пользователя к группе Everyone. Эта специальная группа по определению включает всех сотрудников, и выражение IsUserInRole('Everyone') является тождественно истинным. Это позволяет исключить его из предиката в целях оптимизации.

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

DateAdd(month, 6, ShippedDate) < GetDate()

и

DateDiff(month, ShippedDate, GetDate()) >= 6

хотя и являются математически эквивалентными, скорее всего, помешают оптимизатору СУБД использовать индекс по полю ShippedDate (если он есть).

Атрибуты связанных таблиц

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

ALTER TABLE [Employee]  ADD [DivisionID] int CONSTRAINT [DivisionID_FK]  REFERENCES [Division]([DivisionID])

Новый вариант правила №1 из предыдущего раздела формулируется так:

Менеджеры по продажам (роль ‘Sales Representative’) имеют право просматривать только заказы, введенные менеджерами из того же филиала.

Соответствующая часть предиката безопасности теперь примет такой вид:

(IsUserInRole('Sales Representative')  AND (select DivisionID from Employees where EmployeeID = CurrentEmployeeID()) = (select DivisionID from Employees where EmployeeID = EmployeeID)

Еще один пример правил безопасности, требующий обращения к другим таблицам, связан с защитой подчиненных таблиц. Вместе с записями в таблице заказов необходимо защитить и записи в таблице деталей заказов. Применим правила из предыдущего примера (где еще не было филиалов) к таблице Order Details:

(IsUserInRole('Sales Representative')  AND select(EmployeeID from Orders o where o.OrderID = OrderID) = CurrentEmployeeID())  OR  (IsUserInRole('Vice President, Sales') AND TRUE)  OR  (IsUserInRole('Everyone') AND select(ShippedDate from Orders o where o.OrderID = OrderID) < DateAdd(month, -6, GetDate())

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

create view [Secure Order Details] as select od.* from [Order Details] od  join [Secure Orders] so on od.OrderID = so.OrderID

В таком виде сущность используемого ограничения безопасности очевидна. Кроме того, изменение правил безопасности для заказов (которое повлияет на определение представления Secure Orders) автоматически отразится и на их деталях.

В данном случае мы не накладываем никаких дополнительных ограничений на детали заказа. Однако при необходимости мы можем точно так же добавить локальный предикат безопасности в условие where.

Некоторые итоги

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

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

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


Поделиться с друзьями:

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

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



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.013 с.