WebApi2何时使用OnAuthorizationAsync和OnAuthorization

Sco*_*vis 10 asp.net asp.net-mvc asynchronous azure asp.net-web-api

我们最近通过使用存储在Azure文档数据库中的凭据实现自定义AuthorizationFilterAttribute来实现API身份验证.DocDB要求一切都使用Async.

通过实验我们发现WebApi2同步控制器将使用OnAuthorizationAsync(如果存在),OnAuthorization(如果没有异步方法).我们还发现asyc控制器方法可以使用auth方法.但我不是百分之百确定它是否正常工作.我们只看到代码确实遇到了断点.

奇怪的是,您也可以覆盖OnAuthorization将其标记为异步

公共异步覆盖任务OnAuthorization(....)

最后一个方法编译并执行正常,但控制器不会等待auth过滤器在action方法开始之前完成执行.通常结果是ASP错误:

在异步操作仍处于挂起状态时完成异步模块或处理程序

似乎这种操作覆盖应该是编译错误,不允许.

无论如何......有很多关于AuthorizationFilterAttribute的谜团,还有一些关于混淆的帖子. Asp.net WebApi中的自定义授权 - 真是一团糟?

我的问题是你怎么知道哪个会执行以及哪个优先顺序?如果两者都存在于过滤器中,则会出现,只执行一个方法.

  1. 如果您的控制器操作是异步的,您是否必须覆盖OnAuthorizationAsync方法?

  2. 如果你在auth逻辑中有async await,并且被迫使用OnAuthorizationAsync(就像我一样),那么这是否意味着我必须将所有控制器操作更改为现在都是异步控制器操作?

我找不到任何说明异步操作过滤器方案的文档.

小智 12

如果您查看AuthorizationFilterAttribute的源代码,那么您可以看到OnAuthorizationAsync的基本实现是实际调用OnAuthorization的实现.

public virtual void OnAuthorization(HttpActionContext actionContext)
{
}

public virtual Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
    try
    {
        OnAuthorization(actionContext);
    }
    catch (Exception ex)
    {
        return TaskHelpers.FromError(ex);
    }

    return TaskHelpers.Completed();
}
Run Code Online (Sandbox Code Playgroud)

如您所见,您实际上可以覆盖您想要的任何方法,而您不需要调用基本实现.只需选择一个因为你的场景而生成更多的那个 - 控制器是否异步并不重要.

关于将OnAuthorization本身标记为异步的问题 - 代码编译,因为这是C#异步支持的设计方式,但它确实导致调用代码不等待异步部分完成(它实际上无法等待,因为该方法标记为async void而不是async任务.您可以在此处阅读有关async避免的 更多信息.