стратегия фильтрации данных в соответствии с уровнем доступа пользователя - PullRequest
4 голосов
/ 14 декабря 2009

у нас сейчас очень простая схема безопасности ...

у нас есть ресурсы, которые примерно соответствуют таблицам, у нас есть доступ к этим ресурсам (добавление, изменение, удаление, запрос) и у нас есть группы.

каждое разрешение состоит из ресурса с указанным доступом и группы

и каждый пользователь может принадлежать ко многим группам ...

Итак, разрешение между группой, доступом и ресурсом много-много-много

и у нас также есть много ко многим между пользователем и группой.

это просто отлично для наших нужд ...

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

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

Я думал о добавлении поля «выражения» в таблицу разрешений, чтобы при доступе к определенному ресурсу применялся фильтр (на самом деле это было бы немного сложнее, мне пришлось бы применять каждый фильтр групп к которому принадлежит пользователь, соединенный с "или")

Мне бы хотелось, чтобы это было как можно более общим и настраиваемым ...

Как бы вы справились с таким вариантом использования?

Ответы [ 4 ]

1 голос
/ 23 декабря 2009

У нас есть таблица AccessControlEntry, которая выглядит следующим образом:

CREATE TABLE [dbo].[AccessControlEntry]
(
    [subjectId] [nvarchar](256) NOT NULL,
    [objectType] [varchar](256) NOT NULL,
    [objectId] [int] NOT NULL,
    [permission] [varchar](50) NOT NULL,
    [flag] [int] NOT NULL DEFAULT (0),
    [applyToChildren] [int] NOT NULL DEFAULT (1),
    CONSTRAINT [PK_AccessControlEntry] PRIMARY KEY CLUSTERED ([subjectId] ASC, [objectType] ASC, [objectId] ASC, [permission] ASC)
)

Идентификатором пользователя, для которого мы устанавливаем права доступа, является subjectId, objectType и objectId идентифицируют объект, для которого мы устанавливаем права доступа (Ресурс в вашей терминологии). В нашем случае у нас есть отдельные записи для каждого разрешения (т. Е. Список, просмотр, создание, изменение, удаление), но вы также можете легко получить столбец для каждого разрешения.

Затем мы создали табличную функцию, которая принимает subjectId, objectType и, опционально, objectId и возвращает разрешения.

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

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

1 голос
/ 19 декабря 2009

Ваша идея об использовании «выражений» для фильтров и динамическом создании операторов SQL (верно?) Для фильтрации данных должна работать. Казалось бы, единственная другая реальная альтернатива требует фиксированного набора «осей» фильтра, по которым может быть определен пользовательский доступ к записям. Выбор между двумя основными механизмами требует более подробной информации о вашем приложении. В качестве (очевидного) примера, в приложении моего работодателя каждый клиент (запись) назначается «офису», и мы предоставляем механизмы безопасности для контроля того, какие пользователи могут получить доступ к клиентам в каких офисах. Это реализовано с использованием второго механизма, который я описываю, потому что это очень важно для разработки нашего приложения. Если вы создаете больше «мета-приложения», вы можете захотеть реализовать более общее решение, чтобы вы могли легче изменить это поведение.

1 голос
/ 19 декабря 2009

Я бы настоятельно рекомендовал изучить структуру ORM (Object Relational Mapping), которая способна создавать динамические запросы. Основная идея заключается в том, что вы должны создать критерии в коде приложения на основе безопасности вошедшего в систему пользователя, и среда превращает это в SQL, который выполняется на сервере (поэтому вы не тянете все записи на уровень приложений и не фильтруете их там) ). Разница между этим подходом и использованием прямого динамического SQL заключается в том, что ORM позволит вам писать код, безопасный для типов, где прямой динамический SQL основан на строках, что делает его подверженным человеческим ошибкам.

Некоторые из этих платформ ORM поставляются с готовой функцией авторизации, которая может (или не может) отличаться от описанной выше, но может также выполнять работу.

Я точно знаю, что LLBLGen Pro имеет очень мощный механизм динамических запросов и поддерживает авторизацию на уровне строк. Я не эксперт по NHibernate или Entity Framework, но я уверен, что они также имеют эту поддержку.

Даже если вы не собираетесь использовать ORM для сохранения (их основное назначение), возможно, все же стоит взглянуть на их функции динамических запросов.

1 голос
/ 14 декабря 2009

Я вижу, что у вас еще нет ответов - я, конечно, не уверен, что правильный ответ для вас, но вот мое мнение о том, что это стоит.

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

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

Очень интересует любая поддерживающая / противоречивая точка зрения здесь.

...