Подтвердить что ты не робот

Контроль доступа в доменном дизайне

Я читал о DDD и контроле доступа, и я нашел некоторое противоречие между двумя следующими мнениями:

  • "проблемы безопасности должны выполняться за пределами домена"
  • "требования к управлению доступом являются специфичными для домена"

Я ищу наилучшую практику. Итак, где я должен поместить логику управления доступом с помощью управляемого доменом конструкции и как ее реализовать?

(Чтобы быть более точным с помощью DDD + CQRS + ES.)

Я думаю, что это должно быть где-то рядом с бизнес-логикой, например, пользовательская история может быть примерно такой:

Пользователь может редактировать свой профиль, отправив имя пользователя, список хобби, cv и т.д.

На основе истории пользователей мы реализуем модель домена и сервисы, например:

UserService
    editProfile(EditUserProfileCommand command)
        User user = userRepository.getOneById(command.id)
        user.changeName(command.name)
        user.changeHobbies(command.hobbies)
        user.changeCV(command.cv)

UserRepository
    User getOneById(id)

User
    changeName(String name)
    changeHobbies(String[] hobbies)
    changeCV(String cv)

Это нормально, но где HIS profile часть истории?

Это, очевидно, управление доступом на основе атрибутов, потому что мы должны написать правило примерно так:

deny all, but if subject.id = resource.owner.id then grant access

Но где мы должны применять это правило и как его реализовать?

4b9b3361

Ответ 1

Итак, где я должен поместить логику управления доступом?

В соответствии с этим: 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 года 2016-09-05

Поскольку я ответил на свой вопрос как новичок в DDD, я прочитал Внедрение управляемого доменами от Vaughn Vernon. Это была интересная книга в этой теме. Вот цитата из него:

Это представляет собой новый ограниченный контекст - идентификатор и доступ Контекст - и будет использоваться другими ограничиваемыми контекстами через стандартный Методы интеграции DDD. В контексте потребления идентичность и Контекст доступа - это общий субдомен. Продукт будет называться IdOvation.

Таким образом, согласно Вернону, вероятно, лучшим решением для перемещения контроля доступа в общий поддомен.