15

问题的标题几乎恢复了:我在哪里验证命令的授权?

例如,将客户设置为首选涉及:

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

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

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

SomeView.cshtml

if (authorizationService.Authorize("MarkCustomerAsPreferred))
{
    // show link
}

客户控制器

[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();
}

我的问题是:我需要在 3 个地方验证授权还是我过于热心?

我在整个互联网上搜索,但找不到任何关于此的示例或参考。

编辑

经过更多的研究和一些测试,我认为按照 Dennis Taub 的建议包装命令以添加行为(授权、验证、日志记录)更容易实现。

我发现这篇博客文章准确地解释了这个概念。

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

4

2 回答 2

7

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

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
    }

}
于 2013-06-18T15:10:55.727 回答
3

It's good UI to have that verification in the View, so the user won't click it by mistake. I consider the controller verification the 'real' one, because there is where the command is created. If an user doesn;t have the rights, she shouldn't be able to create (or even reach that action) the command.

I think that putting the check in the handler is a bit overzelous, as it's not its responsibility to do authorization and is not like that handler can be reached by an user directly.

于 2013-06-18T06:12:53.000 回答