Контроль доступа в домене Driven Design


31

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

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

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

(Чтобы быть более конкретным по DDD + CQRS + ES.)

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

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

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

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 

Но где мы должны обеспечить соблюдение этого правила, и как мы должны это осуществить?

  0

Включение идентификатора пользователя в команду ('command.id') вводит неоднозначность. Лучше удалите идентификатор пользователя из команды и передайте пользователя, взятого из контекста авторизации, вместе с командой. 21 фев. 162016-02-21 13:32:17

25

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

В соответствии с этим: 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) 
    
  • по атрибутам на основе контроля доступа (ДКС) определим атрибуты предметные, ресурсов и окружающей среды, и мы пишем нашу политику, основанную на них.

    @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) мы не выполняем идентификацию и аутентификацию, вместо этого мы назначаем разрешения для коэффициентов идентификации. Например, если кто-то отправляет токен, она может иметь доступ к службе. Все остальное похоже на предыдущие решения. Например, с ДКС:

    @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, я прочитал Implementing Domain-Driven Design от Вона Вернон.Это была интересная книга в этой теме. Вот цитата из него:

Это представляет собой новую Локальность контекста - тождественность и доступ контекст - и будет использоваться другими контекстами ограниченных с помощью стандартных методов интеграции DDD. В контексте потребления контекст доступа Identity и является общим поддоменом. Продукт будет называться IdOvation.

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

  0

О редактировании легко перемещаться на основе роли, ACL или на основе разрешений на общий BC, но не столько для авторизации на основе правил. 15 авг. 172017-08-15 16:43:40