The question's title resumes pretty much: where do I verify authorization for a Command?
For example, setting a customer as preferred involves:
MarkAsPreferred
controller action (could be Winforms or whatever);SetCustomerAsPreferredCommand
;SetCustomerAsPreferredCommandHandler
;Customer.MarkAsPreferred()
(domain);
I identified 3 places to check for authorization:
- UI for displaying purposes (user should not see a link/button if he/she does not have access to it);
- controller action to verify the user is authorized to call that command; commands are assumed to always succeed (regarding validation, but I'm assuming authorization too) and we have a chance to inform the user about lack of access;
- inside the command just before calling domain logic;
SomeView.cshtml
if (authorizationService.Authorize("MarkCustomerAsPreferred))
{
// show link
}
CustomerController
[HttpPost]
public ActionResult MarkAsPreferred(Guid id)
{
if (!authorizationService.Authorize("MarkCustomerAsPreferred))
{
return RedirectToAction("Unauthorized");
}
var MarkCustomerAsPreferredCommand { Id = id };
...
}
MarkCustomerAsPreferredCommandHandler
public void Handle(MarkCustomerAsPreferredCommand command)
{
if (!authorizationService.Authorize("MarkCustomerAsPreferred"))
{
throw new Exception("...");
}
customer.MarkAsPreferred();
}
My question is: Do I need to verify authorization in 3 places or I'm just being overzealous?
I searched all over the internet but couldn't find any example or reference about this.
Edit
After more research and some tests I think wrapping the commands to add behavior (authorization, validation, logging) as Dennis Taub suggested is easier and cleaner to implement.
I found this blog post which explains exactly this concept.
About having multiple handlers for one command, I don't need to implement one command handler for each behavior for each original command, one wrapping command can wrap all handlers.