I'm working on implementing my first clean architecture and CQRS application, I've stumbled across a bit of logic that's leaving me a bit stumped. I'm working on integrating authorization and authentication into my application, but I'm having some trouble trying to figure out how to architect a portion of my application that will handle command validation. My system is multitenant and currently shares a database across all of my clients, and I need to implement some sort of system that will enable me to perform all of my verification in a way that is straightforward and not too tightly coupled.
In my system, I have a implementations for both Users
and Clients
. Users can belong to any number clients. These users also have varying levels of permissions granted to them (but this is managed by my roles systems and mostly irrelevant here). My WebAPI is designed in such a way that I limit authorization based on a fixed number of Roles
and Claims
. These largely remain static, so I don't need much flexibility here.
My main source of headache is determining "User-Client" interaction permissions. Namely, I want to determine if a user has access to client that they're attempted to update records for. One approach would be to add UserId
to all of my commands and to individually check the permissions during each command and query. This seems tedious and prone to issues.
Another approach I considered was to define an interface or base class that merely added the client and user Ids to any object in which they were required, but this had the adverse affect of exposing those implementations to my WebAPIs (via swagger and the UserId/ClientId being a portion of the Request/Command object).
One final approach would be to make my underlying commands still implement those interfaces, but have my controller contain minimal logic to map an API request into one of my command objects. Again, this would be tedious and would start leaking my logic into my controllers.
Overall, it's as if I need some additional structure in my application in which I can pipe any object containing a ClientId
into so that I can keep the Authentication
and Authorization
logic out of my core app. However, I'm mostly stumped, and I'm looking for ways that I can simplify my application by minimizing the overhead of adding client-dependent commands and queries.
If it's of any relevance, some of the core tools and technologies I'm leveraging are:
- .Net Core 2.1
- Mediatr
- Entity Framework
And my core application implements commands in a similar fashion to:
public class CreateProductCommand : IRequest
{
public int ClientId { get;set; }
public int ParentProductId { get; set; }
public string ProductName { get; set; }
// other creation specific props here
}
public class CreateProductCommandHandler : IHandler<CreateProductCommand>
{
public async Task<Unit> Handle(CreateProductCommand command)
{
// check parent permissions, make sure parent product
// belongs to client who is entered.
// -----
// rest of logic to save
// -- Ideally the User-Client check would happen before
// -- the command is ever sent to the handler, so that
// -- only client-specific logic and permissions are checked.
// -- As long as the user can edit the specific client, anything
// -- that happens to the client is determined by standard business
// -- and domain logic.
}
}
Task<IActionResult> Product(CreateProductCommand command) => Ok(_mediatr.Send(command);
. I'm trying to keep as much logic out of my controller as possible.