我们最近通过使用存储在 Azure 文档数据库中的凭据实现自定义 AuthorizationFilterAttribute 来实现 API 身份验证。 DocDB 要求一切都使用异步。
通过实验,我们发现 WebApi2 同步 Controller 将使用 OnAuthorizationAsync(如果存在),如果没有异步方法,则使用 OnAuthorization。我们还发现异步 Controller 方法可以使用任一身份验证方法。但我不能 100% 确定它工作正常。我们只看到代码确实遇到了断点。
奇怪的是,您还可以重写 OnAuthorization 将其标记为异步
public async override Task OnAuthorization(....)
最后一个方法编译并执行得很好,但 Controller 不会在操作方法开始之前等待身份验证过滤器完成执行。通常结果是 ASP 错误:
An asynchronous module or handler completed while an asynchronous operation was still pending
似乎这种对覆盖的操作应该是一个编译错误并且不允许。
无论如何......关于 AuthorizationFilterAttribute 有很多谜团,并且存在一些其他关于困惑的帖子。 Custom Authorization in Asp.net WebApi - what a mess?
我的问题是你如何知道哪个将执行以及优先顺序是什么?如果两者都存在于过滤器中,则确实会出现只有一种方法被执行的情况。
如果您的 Controller 操作是异步的,是否必须重写 OnAuthorizationAsync 方法?
如果您的身份验证逻辑中有异步等待,并且被迫使用 OnAuthorizationAsync (就像我一样),这是否意味着我必须将所有 Controller 操作更改为现在全部为异步 Controller 操作?
我找不到任何列出异步操作过滤器场景的文档。
最佳答案
如果您查看 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();
}
正如您所看到的,您实际上可以重写您想要的任一方法,并且不需要调用基本实现。只需选择一个能够为您的场景带来更多 yield 的 Controller - Controller 是否异步并不重要。
关于将 OnAuthorization 本身标记为异步的问题 - 代码会编译,因为这是 C# 异步支持的设计方式,但它确实导致调用代码不等待异步部分完成(它实际上无法等待,因为该方法被标记为async void,而不是async Task。您可以阅读有关asyncvoid的更多信息here .
关于asp.net - WebApi2 何时使用 OnAuthorizationAsync 与 OnAuthorization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29422873/