Я работаю над небольшим приложением, пытаясь понять принципы доменного дизайна. В случае успеха это может быть пилот для более крупного проекта. Я пытаюсь следовать книге «Внедрение доменного дизайна» (Вон Вернон) и пытаюсь реализовать аналогичный простой дискуссионный форум. Я также проверил образцы IDDD на GitHub. У меня есть некоторые трудности с принятием Идентификации и Доступа к моему делу. Позвольте мне дать некоторую справочную информацию:
- Я (надеюсь) понимаю причину разделения логики пользователей и разрешений: это вспомогательный домен, и это другой ограниченный контекст.
- В основном домене нет пользователей, только Авторы, Модераторы и т. Д. Они создаются путем обращения к контексту Identity и Access с помощью службы, а затем трансляции полученных объектов User в и Moderator.
Доменные операции вызываются со связанной ролью в качестве параметра: например:
ModeratePost( ..., moderator);
Метод объекта домена проверяет, является ли данный экземпляр Модератора ненулевым (экземпляр Модератора будет нулевым, если пользователь, запрашиваемый из контекста Identity and Access, не имеет роли Модератора).
В одном случае он выполняет дополнительную проверку перед изменением сообщения:
if (forum.IsModeratedby(moderator))
Мои вопросы:
В последнем случае проблемы безопасности не смешиваются снова в основной области? Ранее в книгах говорилось, «кто может опубликовать тему или на каких условиях это разрешено. Форум просто должен знать, что автор делает это прямо сейчас».
Реализация на основе ролей в книге довольно проста: когда модератор является основным доменом, он пытается преобразовать текущий идентификатор пользователя в экземпляр модератора или в автора, когда это необходимо. Служба ответит соответствующим экземпляром или нулем, если у пользователя нет требуемой роли. Тем не менее, я не вижу, как я мог бы адаптировать это к более сложной модели безопасности; наш текущий проект, для которого я пилотирую, имеет довольно сложную модель с группами, ACL и т. д.
Даже с не слишком сложными правилами, такими как: «Сообщение должно редактировать только его владелец или редактор», этот подход, похоже, не работает, или, по крайней мере, я не вижу правильного способа его реализации.
Запрашивать контекст Identity and Access для экземпляра OwnerOrEditor не совсем правильно, и я получаю все больше и больше связанных с безопасностью классов в основном домене. Кроме того, мне нужно передать не только userId, но и идентификатор защищенного ресурса (id сообщения, форума и т. Д.) В контекст безопасности, который, вероятно, не должен заботиться об этих вещах (это правильно? )
Получив разрешения для основного домена и проверив их в методах объектов домена или в службах, я бы в итоге пришел к выводу: смешивать проблемы безопасности с доменом.
Я где-то читал (и я склонен с этим согласиться), что эти вещи, связанные с разрешениями, не должны быть частью основного домена, если только безопасность и разрешения не являются самим основным доменом. Оправдывает ли простое правило, подобное приведенному выше, обеспечение безопасности как части основного домена?
источник
HasPermissionToEdit(userId, resourceId)
но я не считаю правильным загрязнять логику домена этими вызовами. Вероятно, я должен проверить это в методах службы приложения, прежде чем вызывать логику домена?UserService @AccessControlList[inf3rno]
в ответе, с которым я связан.Ответы:
Иногда трудно различить реальные правила контроля доступа и доменные инварианты, ограничивающие контроль доступа.
В частности, правила, которые зависят только от данных, доступных далеко в ходе определенной части логики домена, не могут быть легко извлечены из домена. Обычно контроль доступа вызывается до или после выполнения операции с доменом, но не во время.
assert (forum.IsModeratedBy(moderator))
Пример Вона Вернона, вероятно, должен был быть за пределами домена, но это не всегда возможно.Если есть Security BC, и вы хотите, чтобы он обрабатывал эту логику, он не должен знать, что такое форум, но:
источник
moderator = securityService.GetModerator(userId, forumId)
4. Доменная логика будет реализована в этих объектах, как в moderator.EditPost () 5. Методы, такие как EditPost, ничего не будут знать о концепциях безопасности, никаких дополнительных проверок не будет тамАутентификация и авторизация - плохой пример для DDD.
Ни одна из этих вещей не является частью домена, если ваша компания не создает продукты безопасности.
Требование к бизнесу или домену: «Требуется проверка подлинности на основе ролей».
Затем вы проверяете роль перед вызовом доменной функции.
Там, где у вас есть сложные требования, такие как «я могу редактировать свои собственные сообщения, но не другие», убедитесь, что ваш домен разделяет функцию редактирования на
EditOwnPost()
и,EditOthersPost()
таким образом, у вас есть простая функция для сопоставления ролей.Вы также можете разделить функциональность на доменные объекты, например,
Poster.EditPost()
иModerator.EditPost()
это более подход ООП, хотя ваш выбор может зависеть от того, находится ли ваш метод в доменной службе или доменном объекте.Однако вы выбираете разделять код, отображение ролей будет происходить за пределами домена. так, например, если у вас есть контроллер webapi:
Как вы можете видеть , хотя отображение роли делаются на хостинг слоя, сложная логика , что представляет собой редактирование вашего собственному или другой пост является частью домена.
Домен распознает разницу в действиях, но требование безопасности заключается просто в том, что «функциональность может быть ограничена ролями» .
Возможно, это более понятно при разделении объектов домена, но по сути вы проверяете метод, который создает объект, а не метод, который вызывает метод службы. Ваше требование, если вы все еще хотите озвучить его как часть домена, станет «только модераторы могут создавать объект модератора»
источник