Так где же мне разместить логику контроля доступа?
Согласно этому: https://softwareengineering.stackexchange.com/a/71883/65755 точка применения политики должна быть прямо перед вызовом UserService.editProfile()
.
Я пришел к такому же выводу: этого не может быть в пользовательском интерфейсе, потому что в нескольких пользовательских интерфейсах мы будем иметь повторение кода. Это должно быть до создания доменных событий, потому что они указывали, что мы уже что-то сделали в системе. Таким образом, мы можем ограничить доступ к объектам домена или к службам, которые используют эти объекты домена. По CQRS у нас нет необходимости иметь объекты домена по модели чтения, только сервисы, поэтому мы должны ограничить доступ к сервисам, если нам нужно общее решение. Мы могли бы помещать решения о доступе в начало каждой операции службы, но это было бы grant all, deny x
антипаттерном безопасности.
Как мне это реализовать?
Это зависит от того, какая модель управления доступом подходит для домена, поэтому это зависит от истории пользователя. Принимая решение о доступе, мы обычно отправляем запрос на доступ и ждем ответного разрешения. Запрос на доступ обычно состоит из следующих частей: тема, ресурс, операция, среда. Таким образом, субъекту требуется разрешение на выполнение операции с ресурсом в среде. Сначала мы идентифицируем субъект, затем аутентифицируем его, а после этого идет авторизация, где мы проверяем, соответствует ли запрос доступа нашей политике доступа. Каждая модель контроля доступа работает одинаково. Ofc. им может не хватать некоторых из этих шагов, но это не имеет значения ...
Я составил небольшой список моделей контроля доступа. Я помещаю правила и политики в аннотации, но обычно мы должны хранить их в базе данных, вероятно, в формате XACML, если мы хотим иметь хорошо обслуживаемую систему ...
При управлении доступом на основе идентичности (IBAC) у нас есть хранилище идентичности - разрешений (список управления доступом, список возможностей, матрица управления доступом). Так, например, с помощью списка управления доступом мы храним список пользователей или групп, у которых могут быть разрешения.
UserService
@AccessControlList[inf3rno]
editProfile(EditUserProfileCommand command)
При управлении доступом на основе решетки (LBAC) субъект имеет уровень допуска, ресурс имеет требуемый уровень допуска, и мы проверяем, какой уровень выше ...
@posseses[level=5]
inf3rno
UserService
@requires(level>=3)
editProfile(EditUserProfileCommand command)
С помощью управления доступом на основе ролей (RBAC) мы определяем роли субъектов и предоставляем разрешения тем субъектам, чьи действия являются фактической ролью.
@roles[admin]
inf3rno
UserService
@requires(role=admin)
editProfile(EditUserProfileCommand command)
Посредством управления доступом на основе атрибутов (ABAC) мы определяем атрибуты субъекта, ресурса и среды и на их основе составляем наши политики.
@attributes[roles=[admin]]
inf3rno
UserService
@policy(subject.role=admin or resource.owner.id = subject.id)
editProfile(EditUserProfileCommand command)
@attribute(owner)
Subject getOwner(EditUserProfileCommand command)
С помощью управления доступом на основе политик (PBAC) мы не назначаем наши политики ничему другому, они автономны.
@attributes[roles=[admin]]
inf3rno
UserService
editProfile(EditUserProfileCommand command)
deleteProfile(DeleteUserProfileCommand command)
@attribute(owner)
Subject getOwner(EditUserProfileCommand command)
@permission(UserService.editProfile, UserService.deleteProfile)
@criteria(subject.role=admin or resource.owner.id = subject.id)
WriteUserServicePolicy
Используя управление доступом с адаптацией к рискам (RAdAC), мы основываем свое решение на профиле относительного риска субъекта и уровне риска операции. Я думаю, это нельзя описать правилами. Я не уверен в реализации, возможно, это то, что stackoverflow использует своей системой баллов.
При управлении доступом на основе авторизации (ZBAC) мы не выполняем идентификацию и аутентификацию, вместо этого мы назначаем разрешения для факторов идентификации. Например, если кто-то отправляет токен, он может получить доступ к услуге. В остальном все аналогично предыдущим решениям. Например, с ABAC:
@attributes[roles=[editor]]
token:2683fraicfv8a2zuisbkcaac
ArticleService
@policy(subject.role=editor)
editArticle(EditArticleCommand command)
Таким образом, любой, кто знает токен 2683fraicfv8a2zuisbkcaac
, может пользоваться сервисом.
и так далее...
Есть много других моделей, и выбор наилучшего всегда зависит от потребностей вашего клиента.
Итак, чтобы подвести итог
- "security concerns should be handled outside the domain"
- "access control requirements are domain specific"
оба могут быть правы, потому что безопасность не является частью модели предметной области, но ее реализация зависит от модели предметной области и логики приложения.
изменить через 2 года 5 сентября 2016 г.
Поскольку я ответил на свой вопрос как новичок в DDD, я прочитал Реализация Домен-ориентированный дизайн от Вона Вернона. Это была интересная книга по теме. Вот цитата из него:
Это составляет новый ограниченный контекст - контекст идентификации и доступа - и будет использоваться другими ограниченными контекстами с помощью стандартных методов интеграции DDD. Для потребляющих контекстов контекст идентификации и доступа является универсальным субдоменом. Продукт будет называться IdOvation.
Так что, по мнению Вернона, возможно, лучшее решение перенести контроль доступа на общий поддомен.
person
inf3rno
schedule
06.05.2014
command.id
) вносит неоднозначность. Лучше удалить идентификатор пользователя из команды и передать пользователя, взятого из контекста авторизации, вместе с командой. - person Lightman   schedule 21.02.2016