If I have an entity Entity and a service EntityService and EntityServiceFacade with the following interfaces:
interface EntityService {
Entity getEntity(Long id);
}
interface EntityServiceFacade {
EntityDTO getEntity(Long id);
}
I can easily secure the read access to an entity by controlling access to the getEntity method at the service level. But once the facade has a reference to an entity, how can I control write access to it? If I have a saveEntity method and control access at the service (not facade) level like this (with Spring security annotations here):
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);
}
}
The problem here is that the access control check happens already after I have changed the name of the entity, so that does not suffice.
How do you guys do it? Do you secure the domain object methods instead?
Thanks
Edit:
If you secure your domain objects, for example with annotations like:
@PreAuthorize("hasPermission(this, 'write')")
public void setName(String name) { this.name = name; }
Am I then breaking the domain model (according to DDD?)
Edit2
I found a thesis on the subject. The conclusion of that thesis says that a good way IS to annotate the domain object methods to secure them. Any thoughts on this?
If
Entityis an interface, can’t you just membrane it?So if Entity looks like this:
create a membrane like
If you annotate read methods, you can use Proxy classes to automatically create membranes that cross multiple classes (so that a get method on a readonly
Entitythat returns anEntityPartreturns a readonlyEntityPart).See deep attenuation in http://en.wikipedia.org/wiki/Object-capability_model for more details on this approach.