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





Место, где вы добавляете безопасность, действительно зависит от того, от кого вы пытаетесь обезопасить себя.
Если, например, вы защищаете веб-сайт, то добавления фильтрации на уровне контекста будет достаточно, потому что «пользователи» в этом случае находятся на веб-сайте. У них нет другого выбора, кроме как пройтись по вашему контексту, поскольку вы бы написали приложение полностью против контекста.
В вашем случае это похоже на то, что «пользователи», от которых вы пытаетесь защитить себя, являются разработчиками. Это немного сложнее. Если у разработчиков нет доступа для внесения изменений в саму базу данных, вам придется установить безопасность на уровне базы данных. Никакой объем доступа к eSQL не сможет обойти базу данных, сказав «нет».
То, чего вы пытаетесь достичь, по определению невозможно.
Если безопасность не обрабатывается явным образом базовым приложением базы данных (SQL Server, Oracle и т. д.), То стандартные инструменты, такие как SQL Management Studio, не выдержат.
Лучшее, что вы можете сделать, - это обеспечить безопасность на уровне строк пользователями приложения, ТОЛЬКО если эти пользователи не имеют доступа к базе данных через другой механизм.
Конечно, ты справишься. Важно заблокировать прямой доступ к контексту объекта (не позволяя пользователям создавать свои собственные ObjectQuery) и вместо этого предоставить клиенту более узкий шлюз для доступа и изменения сущностей. Мы делаем это с помощью Шаблон Entity Repository. Вы можете найти пример реализации этого шаблона для структуры сущностей в этом сообщении в блоге. Опять же, ключ блокирует доступ к контексту объекта. Обратите внимание, что класс контекста объекта является частичным. Таким образом, вы должны иметь возможность предотвратить «неавторизованные» средства его создания, а именно за пределами сборки вашего репозитория.
Однако здесь есть свои тонкости. Если вы реализуете безопасность представления на уровне строк для определенного типа сущности через шаблон репозитория, тогда вы должны рассмотреть другие средства, с помощью которых клиент может получить доступ к тем же сущностям. Например, через навигационные отношения. Возможно, вам придется сделать некоторые из этих отношений конфиденциальными, что вы можете сделать в своей модели. У вас также есть опция указание настраиваемого запроса или хранимая процедура для загрузки / сохранения сущностей. Хранимые процедуры, как правило, зависят от сервера БД, но SQL может быть написан в общем виде.
Хотя я не согласен с тем, что это невозможно сделать с помощью Entity Framework, я согласен с комментариями «сделайте это на сервере БД», поскольку вы должны реализовать глубокая защита.
Вы можете найти эту статью полезной:
http://msdn.microsoft.com/en-us/magazine/ff898427.aspx
«Запретить доступ таблиц к Entity Framework, не вызывая мятежа»
Я нашел способ сделать это с помощью Postgres и расширения под названием Вуаль. На самом деле он работает (предназначен) с использованием Views для всех операций (выбор, обновление, удаление, вставка) и проверки разрешений в разделах WHERE. Но Veil просто добавляет математику для эффективного управления информацией о разрешениях в памяти вместо того, чтобы запрашивать ее каждый раз. Итак, с Veil, хотя вы подключаетесь напрямую к СУБД, вам предоставляется только доступ на уровне строк.
В некотором роде я модифицирую свой стиль с помощью вуали, например, я начал использовать Triggers вместо Views для применения ограничений разрешений.
Я рекомендую вам изучить это решение и попробовать применить его логику здесь.
то есть: вы делаете запрос select * from table и получаете именно то, что намеревались (говоря на уровне строки).
Обратите внимание, что в SQL Azure и SQL Server 2016 теперь встроена защита на уровне строк, и ее можно использовать с Entity Framework. Вот учебник azure.microsoft.com/en-us/documentation/articles/…