ASP NET CORE DDD - CurrentUserService in Domain layer

Viewed 214

I am working on a school project which basically acts like a Messenger with Events etc.

Recently I came across DDD and I decided to try to implement it's concepts in my project.

I ran into a problem, where each time I want to edit an entity I need to check, if a currently logged user has rights for it.

I have CommmunicationChannel entity (AR) which has ICollection<CommunicationChannelMessage>. When I want to edit message I need to load CommunicationChannel entity, find CommunicationChannelMessage in it and then check if currently logged user is the author of the message.

I decided to create DomainService MessageManager, which has method Update(CommunicationChannel channel, string messageId, string newContent). This method loads the message or throws NotFoundException, after that it check, if user has right to it and if not throws ForbiddenAccessException.

Basically, domain layer now has a responsibility to check if currently logged user has rights to do something. The idea behind this is that there will be no place in code, where I can forget to check permissions of the user. I can only call methods from this manager and they check permissions everytime.

So my question is following. Can a domain service have a reference to ICurrentUserService (returns entity of currently logged user). Shouldn't the check of user permission be application specific concern in Application layer instead of domain layer?

Thank you so much for your answer.

1 Answers

Stricto sensu DDD does not states anything regarding application layering, besides :

  • domain layer must use object modeling
  • domain layer is where business rules are implemented

Now the problem must also be split in two different security concepts : authentication (find user identity) and authorization (is user allowed). Authentication is always an application cross cutting concern, usually handled by an asp.net middleware like Kerberos, OIDC, etc ...

You have two approaches possible for your authorization problem : consider the identity verification as a business requirement or a security cross cutting concern.

In case of a business requirement, author must exist in the domain model, at least as a login/username property on message. Add a parameter to your Update() method for actual user identity to be compared with message author. Your controller can pass the user identity from asp net core authentication or any external auth service if a conversion is required.

If you want to make that a cross cutting concern, you don't need to model message author (unless useful for another business requirement). Make a custom middleware, or insert a security layer somewhere in your architecture (a more precise answer would require insights on your actual architecture).

Related