Proper way to secure domain objects? - security

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?

I wouldn't worry about securing individual entity methods or properties from being modified.
Preventing a user from changing an entity in memory is not always necessary if you can control persistence.
The big gotcha here is UX, you want to inform a user as early as possible that she will probably be unable to persist changes made to that entity. The decision you will need to make is whether it is acceptable to delay the security check until persistence time or if you need to inform a user before (e.g. by deactivating UI elements).

If Entity is an interface, can't you just membrane it?
So if Entity looks like this:
interface Entity {
int getFoo();
void setFoo(int newFoo);
}
create a membrane like
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(); }
}
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 Entity that returns an EntityPart returns a readonly EntityPart).
See deep attenuation in http://en.wikipedia.org/wiki/Object-capability_model for more details on this approach.

Related

DDD Aggregate needs info from another aggregate

i'm stuck with this problem while designing aggregates in a DDD project.
Please consider the following scenario:
public abstract class BaseAppType{
public abstract int GetUserOwnerId();
public List<AppTypeHost> Hosts {get;set;} = new List<AppTypeHost>()
}
public class PersonalAppType:BaseAppType //this is an aggregate root
{
public int override GetUserOwnerId(){ return Hosts.Select(h=>h.UserId).Single(); }
}
public class TeamAppType:BaseAppType //this is another aggregate root
{
publi int TeamOwnerId {get;set;}
public int override GetUserOwnerId(){ //this is much harder becase i don't have the info in the object }
}
public class Team {
public List<TeamMember> TeamMembers = new List<TeamMember>();
}
public class TeamMember {
public int TeamId {get;set;}
public int UserId {get;set;}
public TeamMemberRole Role {get;set;} //this might be either Owner or Member
}
So basically i've two types of appointments that share common info, functionality and shape via a root class.
Now i've to implement GetUserOwnerId in the two derived class, which are two distinct aggregates root.
In the PersonalAppType it is kind of easy because the information of the userOwner is within one of the entity of the aggregate so i simply query the object in memory and return it.
In the TeamAppType it is more diffuclt because the information is in another aggregate root ( basically for my business rules, the owner of the TeamAppType is the Owner of the Team AggregateRoot).
Since Team is another AggregateRoot i could not load it into the TeamAppType aggregate and i pretty stuck...
I've tried:
the route of injecting a service in the TeamAppType
so that i can call it within the GetUserOwnerId but i don't like it because it feel "wrong" to inject a service within a domain constructor and it is kind of hard because when i retrieve the aggregate root from ef core, it doesn't inject the service ( because it uses the default construcor with 0 params )
I've also tried the route of doing it in a domain service, something like this:
public class AppTypeOwnerResolverService{
public int GetUserOwnerId (BaseAppType appType)
{
switch (appType.GetType())
{
case "PersonalAppType":
//retrieve owener of PersonalAppType
break
case "TeamAppType":
//retrieve owener of TeamAppType
break
}
}
}
but it feels off because it looks like the GetUserOwnerId should stay within the inherited class and this reduces the benefits of polymorfism.
Do you have any suggestion on how to approach this problem?
Thanks to everyone for the help.
Another option would be to have a Team aggregate emitting domain events, (i.e. TeamOwnerAssigned) and having a domain event handler that modifies the TeamAppType aggregate based on this event.

Object creation events in ServiceStack's OrmLite

I need to set an event handler on objects that get instantiated by OrmLite, and can't figure out a good way to do it short of visiting every Get method in a repo (which obviously is not a good way).
To give some background - say I have a class User, which is pulled from database; it also implements INotifyPropertyChanged. I want to assign a handler to that event. Having it auto-populated from Funq would be ideal, but of course OrmLite doesn't ask Funq to hydrate the new object.
So I'm stuck.
Any hints in a right direction would be appreciated.
It sounds to me like you're mixing in presentation logic with your data access logic. If I was in your position I would not attempt to implement INotifyPropertyChanged on a model (such as your User class). Instead I would create a ViewModel and place the databinding logic there (MVVM Style).
Having INotifyPropertyChanged on the data model is not quite logical when you get down to it. If I were to update the database record it would not fire this event for example (but the property has changed). It makes a lot more sense on a ViewModel.
Beyond solving your original issue it also makes building complex screens a lot easier by letting you aggregate, compose, and filter data for display purposes. If you need to pull in information from your database, a RSS feed, a stock ticker web API, and twitter you can do so in your ViewModel.
public class User
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
}
public class UserViewModel : INotifyPropertyChanged
{
private string _name;
public UserViewModel(User user)
{
_name = user.Name;
}
public string Name
{
get { return _name; }
set {
if (value == _name) return;
_name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Small Note: This answer was written in the context of display data on a screen with a ViewModel, however, the same concept applies to observing model changes for any purpose.

UnitOfWork / working with multiple databases in a DDD application

We have an application which stores its data in two different databases. At some point in the future we may only be storing our data in one database, so we want it to be as painful as possible to make this kind of change. For this reason, we wrap our DbContexts in a single MyDataContext which gets injected into our UnitOfWork and Repository classes.
class MyDataContext : IDataContext {
internal Database1Context Database1;
internal Database2Context Database2;
}
class UnitOfWork : IUnitOfWork {
MyDataContext myDataContext;
public UnitOfWork(MyDataContext myDataContext) {
this.myDataContext = myDataContext;
}
public Save() {
//todo: add transaction/commit/rollback logic
this.myDataContext.Database1.SaveChanges();
this.myDataContext.Database2.SaveChanges();
}
}
class Database1Context : DbContext {
public DbSet<Customer> Customers { get; set; }
}
class Database2Context : DbContext {
public DbSet<Customers> CustomerProfile { get; set; }
}
class CustomerRepository : ICustomerRepository {
MyDataContext myDataContext;
public CustomerRepository(MyDataContext myDataContext) {
this.myDataContext = myDataContext;
}
public GetCustomerById(int id) {
return this.myDataContext.Database1.Customers.Single(...);
}
}
My first question is, am I doing it right? I've been doing a lot of reading, but admittedly DDD is a little bit overwhelming at this point.
My second question is which layer of the application do the IUnitOfWork and IDataContext interfaces reside in? I know that the interfaces for repositories live in the Core/Domain layer/assembly of the application, but not sure about these two. Should these two even have interfaces?
My first question is, am I doing it right?
You can do that, but first reconsider why you're storing data in different places in the first place. Are distinct aggregates at play? Furthermore, if you wish to commit changes to two different databases within a transaction, you will need to use 2-phase commit which is best to avoid. If you have different aggregates, perhaps you can save them separately?
My second question is which layer of the application do the
IUnitOfWork and IDataContext interfaces reside in?
These can be placed in the application layer.

Bads of rich domain model

I was reading about anemic domain model is a antipattern and I had some questions about.
I have a database where three clients uses and each one of them has diferrents business rules to insert a product into database.
So, if I use a rich domain model, my code will be something like this:
public class Product: IValidatableObject
{
public int Id;
public Client Client;
public int ClientId;
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ClientId == 1)
DoValidationForClientOne();
else if (ClientId == 2)
DoValidationForClientTwo();
else if (ClientId == 3)
DoValidationForClientThree();
}
}
well, it's horrible, isn't?
Now if I have an anemic domain model I could simple create three services layer classes where each one of them would contain a validation for one especific client. Isn't it good?
My second argument is: if I have a desktop and a web application using the same rich domain model, how can I know when to throw a HttpException and when to throw some desktop exception? Wouldn't it better to separate it?
So, finally, why an anemic domain model is an anti pattern in a situation like this in my project?
An AnaemicDomainModel has its place: https://softwareengineering.stackexchange.com/questions/160782/are-factors-such-as-intellisense-support-and-strong-typing-enough-to-justify-the
Your domain model should not be throwing exceptions that are specific to a presentation platform. Let your presentation code sort that out. You should aim to make your domain model agnostic of its presentation.
As already stated - you showed just a DTO, not a domain entity.
In DDD, you would have some constant rules directly in Product entity and some number of ProductPolicies to encapsulate what can differ in handling products in defferent contexts. Horrible? No. Beautiful and powerful. But only if your domain is complex enough. If it's not - use an anemic model.
Your domain should not depend on anything. Should not know anything about web platform, desktop platform, ORM being used, DI container being used. So if you throw an exception, it should be a domain custom exception. Read about onion architecture or hexagonal architecure for more detailed explanation: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
I will recommend following:
Define IProductValidator interface, and provide 3 implementations as:
interface IProductValidator {
void validateProduct(Product product);
}
Change Client class, and add following methods to it
class Client {
void validateProduct(Product product) {
getProductValidator().validate(product);
}
IProductValidator getProductValidator() {
// this method returns validator, and it's better the method
// be abstract, and be implemented in sub-classes according
// to their type
}
}
And change the Product class to:
public class Product: IValidatableObject {
public int Id;
public Client client;
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
client.validate(this);
}
}
Now tou

Automapper and immutability

Is it possible to use AutoMapper with Immutable types?
For example my Domain type is immutable and I want to map my view type to this.
I believe it is not but just want this confirmed.
Also as it is best practice to have your domain types immutable, what is the best practice when mapping your view types to domain types?
I typically do the mapping from view types to domain types by hand, as I'll typically be working through a more complex interface, using methods and so on. If you use AutoMapper to go from view to domain, you're now locked in to an anemic domain model, whether you've intentionally decided to or not.
Suppose that you really did want an immutable property on your Domain type, say Id. Your domain type might look something like this:
public class DomainType
{
public DomainType(int id)
{
Id = id;
}
public int Id { get; }
// other mutable properties
// ...
}
Then you can use ConstructUsing using a public constructor of your choice, such as:
CreateMap<ViewType, DomainType>()
.ConstructUsing(vt => new DomainType(vt.Id));
Then map all the mutable properties in the normal way
AutoMapper relies on property setters to do its work, so if you have read-only properties, AutoMapper won't be of much use.
You could override the mapping behaviour and, for example, configure it to invoke a specific constructor, but that basically defeats the purpose of AutoMapper because then you are doing the mapping manually, and you've only succeeded in adding a clumsy extra step in the process.
It doesn't make a lot of sense to me that your domain model is immutable. How do you update it? Is the entire application read-only? And if so, why would you ever need to map to your domain model as opposed to from? An immutable domain model sounds... pretty useless.
P.S. I'm assuming that you mean this AutoMapper and not the auto-mapping feature in Fluent NHibernate or even some other totally different thing. If that's wrong then you should be more specific and add tags for your platform/language.
We have immutable objects using the builder pattern. Mapping them takes a little more boilerplate code, but it is possible
// ViewModel
public class CarModel : IVehicleModel
{
private CarModel (Builder builder)
{
LicensePlate = builder.LicensePlate;
}
public string LicensePlate { get; }
//
public Builder
{
public string LicensePlate { get; set; }
}
}
// Model
public class CarViewModel : IVehicleViewModel
{
private CarViewModel (Builder builder)
{
LicensePlate = builder.LicensePlate ;
}
public ILicensePlate LicensePlate { get; }
//
public Builder
{
public ILicensePlate LicensePlate { get; set; }
}
}
Our AutoMapper Profiles have three mappings registered:
CreateMap<IVehicleModel, CarViewModel.Builder>();
CreateMap<CarViewModel.Builder, IVehicleViewModel>().ConvertUsing(x => x.Build());
CreateMap<IVehicleModel, IVehicleViewModel>().ConvertUsing<VehicleModelTypeConverter>();
The VehicleModelTypeConverter then defines a two stage conversion:
public IVehicleViewModel Convert(IVehicleModel source, IVehicleViewModel destination,
ResolutionContext context)
{
var builder = context.Mapper.Map<CarViewModel.Builder>(source);
var model = context.Mapper.Map<IVehicleViewModel>(builder);
return model;
}
(An implementation of ITypeListConverter<string, ILicensePlate> carries out that mapping).
Usage in our system is as normal:
var result = _mapper<IVehicleViewModel>(_carModel);
This is using AutoMapper v7.0.1
You can use Automapper with classes or records that have properties init only setters. This is new in C# 9.0.
Automapper can set the properties at object creation because the properties have init only setters, but after Automapper has mapped them, they are locked in (immutable).
https://www.tsunamisolutions.com/blog/c-90-records-and-dtos-a-match-made-in-redmond

Resources