Безопасность уровня строки с платформой Entity

Я пытался понять, как Row Level Security может быть реализована с помощью Entity Framework. Идея заключается в том, что агностические средства базы данных будут предлагать методы для ограничения строк, поступающих из ObjectContext.

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

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

Ответ 1

Конечно, вы можете это сделать. Важно сделать так, чтобы блокировать прямой доступ к контексту объекта (не позволяя пользователям создавать собственный ObjectQuery) и вместо этого предоставлять клиенту более узкий шлюз, в который можно получить доступ и изменить сущности. Мы делаем это с шаблон репозитория объектов. Вы можете найти пример реализации этого шаблона для структуры сущности в этом сообщении в блоге. Опять же, ключ блокирует доступ к контексту объекта. Обратите внимание, что класс контекста объекта является частичным. Таким образом, вы должны быть в состоянии предотвратить "несанкционированные" способы создания экземпляра, а именно вне сборки вашего репозитория.

Однако есть тонкости для рассмотрения. Если вы реализуете безопасность представления на уровне строк по определенному типу сущности через шаблон репозитория, тогда вы должны рассмотреть другие способы, с помощью которых клиент мог получить доступ к тем же объектам. Например, через навигационные отношения. Возможно, вам придется сделать некоторые из этих отношений частными, что вы можете сделать в своей модели. У вас также есть опция Указание пользовательского запроса или хранимую процедуру для загрузки/сохранения юридические лица. Хранимые процедуры, как правило, специфичны для сервера БД, но SQL может быть написан общим образом.

Хотя я не согласен с тем, что это невозможно сделать с помощью платформы Entity Framework, я согласен с комментариями "сделайте это на сервере БД", поскольку вы должны реализовать в глубину.

Ответ 2

Место, где вы добавляете безопасность, действительно зависит от того, с кем вы пытаетесь защитить.

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

В вашем случае это звучит так, как "пользователи", с которыми вы пытаетесь защитить, - это разработчики. Это довольно сложно. Если разработчики не имеют доступа для внесения изменений в саму базу данных, вам необходимо будет установить безопасность на уровне базы данных. Никакой объем доступа к eSQL не сможет обойти базу данных, говоря "нет".

Ответ 3

То, что вы пытаетесь достичь, по определению не представляется возможным.

Если безопасность не обрабатывается явным образом базовым приложением базы данных (SQL Server, Oracle, независимо), тогда стандартные инструменты, такие как SQL Management Studio, будут удалены прямо мимо него.

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

Ответ 5

Я нашел способ сделать это, используя Postgres и расширение, называемое Veil. Он фактически работает (предназначен для) с помощью Views для всех операций (выберите, обновите, удалите, вставьте) и проверите разрешения в предложениях WHERE. Но Veil просто добавляет математику для эффективного управления информацией о разрешении в памяти вместо того, чтобы запрашивать ее каждый раз. Так что с Veil, хотя вы напрямую подключаетесь к СУБД, у вас есть только доступ на уровне строк, предоставленный вам.

Я каким-то образом модифицирую свой стиль с вуалью, например, я начал использовать Triggers вместо Views для применения ограничений разрешений.

Я рекомендую вам изучить это решение и попытаться применить его здесь.

i.e: Вы делаете запрос select * from table, и вы получаете именно то, что вы намерены (речь на уровне строк).