我们最近通过使用存储在Azure文档数据库中的凭据实现自定义AuthorizationFilterAttribute来实现API身份验证。 DocDB要求一切都使用Async。
通过实验我们发现WebApi2同步控制器将使用OnAuthorizationAsync(如果存在),OnAuthorization(如果没有异步方法)。我们还发现asyc控制器方法可以使用auth方法。但我不是百分之百确定它是否正常工作。我们只看到代码确实遇到了断点。
奇怪的是,你也可以覆盖OnAuthorization,将其标记为async
公共异步覆盖任务OnAuthorization(....)
这最后一个方法编译并执行正常,但控制器不会等待auth过滤器在action方法开始之前完成执行。通常结果是ASP错误:
在异步操作仍处于挂起状态时完成异步模块或处理程序
似乎这种对覆盖的操作应该是编译错误而不允许。
无论如何......有很多关于AuthorizationFilterAttribute的谜团,还有一些关于混淆的帖子。 Custom Authorization in Asp.net WebApi - what a mess?
我的问题是你怎么知道哪个会执行以及哪个优先顺序?如果两者都存在于过滤器中,则会出现,只执行一个方法。
如果您的控制器操作是异步的,您是否必须覆盖OnAuthorizationAsync方法?
如果您在auth逻辑中有异步等待,并且被迫使用OnAuthorizationAsync(就像我一样),那么这是否意味着我必须将所有控制器操作更改为现在都是异步控制器操作?
我找不到任何说明异步操作过滤器方案的文档。
答案 0 :(得分:11)
如果您查看 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();
}
正如您所看到的,您实际上可以覆盖您想要的任何一种方法,并且您不需要调用基本实现。只需选择一个因为你的场景而生成更多的那个 - 如果控制器是异步的,那就不重要了。
关于将 OnAuthorization 本身标记为异步的问题 - 代码编译,因为C#异步支持的设计方式,但它确实导致调用代码不等待要完成的异步部分(它实际上无法等待,因为该方法被标记为 async void 而不是 async Task 。您可以阅读有关 async avoid <的更多信息/ em> here。