Правильный способ защиты доменных объектов? - PullRequest
1 голос
/ 15 ноября 2010

Если у меня есть сущность Entity и служба EntityService и EntityServiceFacade со следующими интерфейсами:

interface EntityService {

 Entity getEntity(Long id);

}

interface EntityServiceFacade {

 EntityDTO getEntity(Long id);

}

Я могу легко защитить доступ для чтения к объекту, контролируя доступ к методу getEntity на уровне обслуживания,Но как только у фасада есть ссылка на сущность, как я могу контролировать доступ на запись к нему?Если у меня есть метод saveEntity и контроль доступа на уровне сервиса (не фасада), как это (с аннотациями безопасности Spring здесь):

class EntityServiceImpl implements EntityService {

 ...

 @PreAuthorize("hasPermission(#entity, 'write')")
 public void saveEntity(Entity entity) {

  repository.store(entity);
 }

}

class EntityServiceFacadeImpl implements EntityServiceFacade {

 ...

 @Transactional
 public void saveEntity(EntityDTO dto) {

  Entity entity = service.getEntity(dto.id);
  entity.setName(dto.name);
  service.save(entity);
 }

}

Проблема здесь в том, что проверка контроля доступа происходит уже после того, как яизменил название сущности, так что этого недостаточно.

Как вы, ребята, делаете это?Вместо этого вы защищаете методы объекта домена?

Спасибо

Редактировать:

Если вы защищаете свои объекты домена, например, с помощью аннотаций, таких как:

@PreAuthorize("hasPermission(this, 'write')")
public void setName(String name) { this.name = name; }

Разбиваю ли я тогда модель предметной области (согласно DDD?)

Edit2

Я нашел тезис на предмет.В заключении этого тезиса говорится, что хорошим способом является аннотирование методов объекта домена для их защиты.Есть мысли по этому поводу?

Ответы [ 2 ]

2 голосов
/ 15 ноября 2010

Я бы не стал беспокоиться о защите отдельных методов или свойств сущностей от изменения.

Запрещение пользователю изменять сущность в памяти не всегда необходимо, если вы можете контролировать постоянство.

Большая проблема здесь - UX, вы хотите как можно раньше сообщить пользователю, что он, вероятно, не сможет сохранить изменения, внесенные в эту сущность. Вам нужно будет принять решение: допустимо ли отложить проверку безопасности до продолжительного времени или вам нужно заранее проинформировать пользователя (например, путем деактивации элементов интерфейса).

1 голос
/ 18 ноября 2010

Если Entity - это интерфейс, разве вы не можете просто подключить его?

Итак, если сущность выглядит так:

interface Entity {
  int getFoo();
  void setFoo(int newFoo);
}

создать мембрану типа

final class ReadOnlyEntity implements Entity {
  private final Entity underlying;

  ReadOnlyEntity(Entity underlying) { this.underlying = underlying; }

  public int getFoo() { return underlying.getFoo(); }  // Read methods work

  // But deny mutators.
  public void setFoo(int newFoo) { throw new UnsupportedOperationException(); }
}

Если вы аннотируете методы чтения, вы можете использовать прокси-классы для автоматического создания мембран, которые пересекают несколько классов (так что метод get для readonly Entity, который возвращает EntityPart, возвращает readonly EntityPart).

См. Глубокое затухание в http://en.wikipedia.org/wiki/Object-capability_model для более подробной информации об этом подходе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...