Должны ли проблемы безопасности присутствовать в модели предметной области?
Я работаю над проектом Winforms (.NET 4), который свободно основан на MVVM. В целях безопасности приложение проходит проверку подлинности в Active Directory, а затем использует безопасность на основе ролей для определения разрешений на доступ к различным частям программы. Безопасность реализуется с помощью атрибута PrincipalPermissionAttribute в большинстве мест, например так:
<PrincipalPermissionAttribute(SecurityAction.Demand, Role:="Managers")> _
Public Sub Save() Implements IProductsViewModel.Save
mUOW.Commit()
End Sub
Как вы, вероятно, можете сказать из реализации интерфейса, этот конкретный Sub находится в ViewModel. PrincipalPermissionAttribute проверяет, находится ли текущий пользователь (Thread.CurrentPrincipal) в роли диспетчера.
Что приводит к моему вопросу: должны ли проверки безопасности (такие как выше) выполняться в доменной модели?
У меня есть два противоречивых мнения, когда я думаю об этом сам:
1) Держите модель предметной области в неведении о многих других проблемах, чтобы уменьшить сложность и зависимость. (Хранить в безопасности, возможно, реализовано во ViewModel).
2) Модель предметной области - это, в некотором смысле, место, где "доллар здесь останавливается". Если я реализую безопасность в модели предметной области, то я знаю, что даже если защита на другом уровне терпит неудачу, модель предметной области должна ее поймать.
Итак, что вы говорите, безопасность в доменной модели или нет?
3 ответа
Лично я считаю, что эта проблема относится к уровню обслуживания. Предположительно, приложение будет в той или иной степени сохраняться на уровне обслуживания, чтобы достичь домена, и вы могли бы легко иметь не доменную службу для проверки роли пользователя до принятия.
Причина, по которой я бы сделал это таким образом, основана на теории, что чем ближе вы подходите к ядру домена, тем дороже становится стек вызовов. Предотвращение злоупотребления / неправильного использования домена на более высоком уровне означает лучшую отзывчивость и сплоченность.
Кроме того, предположим, что требование изменяется, тогда как кто-то в другой роли может теперь выполнить ту же операцию. Поддержание их всех на уровне сервиса означает, что вы также не меняете код, который должен реже использоваться. По крайней мере, в том, что я сделал, положительный вывод заключается в том, что чем ближе к ядру вы получаете, тем меньше вероятность изменения кода. Это означает, что вы также уменьшите изменение своего изменения, чтобы оно стало "волноваться" в других областях, которые вы не намеревались.
Что касается более широкой проблемы и ничего личного, мне не нравится идея добавления доступа к данным любого вида во ViewModel. ViewModel предназначен для представления модели, специфичной для реализации. Эти объекты в идеале должны быть максимально легкими. Например, если в продукт вносится изменение, оно будет передаваться через службу, а затем в хранилище, где оно может быть зарегистрировано в единице работы, ожидая принятия.
Есть 2 вида безопасности.
Тот, который является чисто техническим - что-то вроде "весь трафик должен проходить через https" или "только конкретная служба должна касаться базы данных" или "только конкретный процесс должен иметь возможность касаться файловой системы / реестра".
Второй, связанный с доменом. Что-то вроде "только пользователь с ролью секретаря может получить доступ к истории платежей" или "неавторизованные пользователи не должны иметь доступ к учетным данным".
Сначала нужно отделить от домена. Второй должен жить внутри домена.
Отличные ответы здесь. Я думаю, это зависит от уровня детализации вашей системы разрешений. Допустим, мы разрабатываем «Систему управления задачами» и хотим, чтобы пользователи ограничивали видимость на уровне «Проект».
- Мы могли бы разработать одну общую роль или разрешение «может читать», которое адресовано всем проектам.
- Мы могли бы пойти глубже и реализовать систему, подобную ЦАП, где мы хотим ответить на вопрос «может ли этот пользователь прочитать этот конкретный объект». Это означает, что каждый "Проект" имеет свое собственное "Разрешение на чтение", что не позволяет нам реализовывать его иначе, чем на уровне домена (или очень близко выше).