在哪里验证命令的授权?

Lui*_*mim 13 authorization cqrs

问题的标题重新开始:我在哪里验证命令的授权?

例如,将客户设置为首选包括:

  • MarkAsPreferred 控制器动作(可以是Winforms或其他);
  • SetCustomerAsPreferredCommand;
  • SetCustomerAsPreferredCommandHandler;
  • Customer.MarkAsPreferred() (域);

我确定了3个地方来检查授权:

  • 用于显示目的的UI(如果用户没有访问权限,用户不应该看到链接/按钮);
  • 控制器动作以验证用户是否有权调用该命令; 假设命令总是成功(关于验证,但我也假设授权),我们有机会告知用户缺乏访问权限;
  • 在调用域逻辑之前的命令内部 ;

SomeView.cshtml

if (authorizationService.Authorize("MarkCustomerAsPreferred))
{
    // show link
}
Run Code Online (Sandbox Code Playgroud)

CustomerController

[HttpPost]
public ActionResult MarkAsPreferred(Guid id)
{
    if (!authorizationService.Authorize("MarkCustomerAsPreferred))
    {
        return RedirectToAction("Unauthorized");
    }

    var MarkCustomerAsPreferredCommand { Id = id };
    ...
}
Run Code Online (Sandbox Code Playgroud)

MarkCustomerAsPreferredCommandHandler

public void Handle(MarkCustomerAsPreferredCommand command)
{
    if (!authorizationService.Authorize("MarkCustomerAsPreferred"))
    {
        throw new Exception("...");
    }

    customer.MarkAsPreferred();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:我是否需要在3个地方验证授权,或者我只是过度热心?

我搜索了整个互联网,但没有找到任何关于此的例子或参考.

编辑

经过更多研究和一些测试后,我认为包装命令以添加行为(授权,验证,日志记录),正如Dennis Taub所建议的那样,实施起来更容易,更清晰.

我发现这篇博文正好解释了这个概念.

关于为一个命令设置多个处理程序,我不需要为每个原始命令的每个行为实现一个命令处理程序,一个包装命令可以包装所有处理程序.

Den*_*aub 5

我认为最终授权应该在应用程序服务级别上完成,即作为处理命令的一部分.例如,您可以使用授权处理程序包装命令处理程序.

class AuthorizationHandler : IHandle<SetCustomerAsPreferred> {

    IHandle<SetCustomerAsPreferred> innerHandler;

    public AuthorizationHandler(IHandle<SetCustomerAsPreferred> handler)
    {
        innerHandler = handler;
    }

    public void Handle(SetCustomerAsPreferred command) 
    {
        if (/* not authorized */)
            throw ...
        innerHandler.Handle(command);
    }

}

class SetCustomerAsPreferredCommandHandler : IHandle<SetCustomerAsPreferred> {

    public void Handle(SetCustomerAsPreferred command) 
    {
        // do the work
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 从我的角度来看,这种方法有点臭,因为你为同一个命令定义了2个处理程序.我认为应该在发出命令时进行验证检查.至少用asp.net mvc我有一个授权过滤器(也可能适用于web api).这是一个偏好的问题.@LuizDamim至少我的ServiceBus(我最近写的)可以选择在进行自动配置时忽略某些类型,而且你正在使用的服务总线也有这个选项. (2认同)