WebApi2何时使用OnAuthorizationAsync和OnAuthorization

时间:2022-11-26 13:25:39

We've recently implemented API authentication by implementing a custom AuthorizationFilterAttribute, using credentials stored in Azure Document DB. DocDB mandates everything use Async.

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

Through experimenting we found that WebApi2 synchronous controllers will use the OnAuthorizationAsync if present, and OnAuthorization if no async method. We also found that asyc controller methods can use either auth method. But I'm not 100% sure it is working correctly. We only saw that code did hit breakpoints.

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

Oddly, you can also override OnAuthorization mark it as async

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

public async override Task OnAuthorization(....)

public async override Task OnAuthorization(....)

This last method compiles and executes fine, but the controller will not wait for the auth filter to finish executing before the action method begins. Usually the result is an ASP error:

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

An asynchronous module or handler completed while an asynchronous operation was still pending

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

Seems like this manipulation of the override should have been a compile error and not allowed.

似乎这种对覆盖的操作应该是编译错误而不允许。

Regardless.... There are many mysteries about AuthorizationFilterAttribute and a few other posts exist about the confusion. Custom Authorization in Asp.net WebApi - what a mess?

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

My question is how do you know which will execute and in which order of precedence? It does appear if both exist in the filter, only one method is executed.

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

  1. If your controller action is async, must you override the OnAuthorizationAsync method?

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

  2. If you have async await in your auth logic, and are forced to use OnAuthorizationAsync (like I am), does this then mean I have to change all my controller actions to now all be async controller actions?

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

I can't find any documentation that lays out scenarios for async action filters.

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

1 个解决方案

#1


8  

If you take a look at the source code of AuthorizationFilterAttribute then you can see that the base implementation of OnAuthorizationAsync is the one actually calling OnAuthorization.

如果您查看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();
}

As you can see, you can actually override either method you want and you don't need to call the base implementation. Just choose the one which makes more since for your scenario - it doesn't matter if the controller is async or not.

如您所见,您实际上可以覆盖所需的任何方法,而无需调用基本实现。只需选择一个可以为您的场景提供更多功能的那个 - 控制器是否异步并不重要。

And regarding your question about marking OnAuthorization itself as async - the code compiles since that's the way C# async support is designed, but it indeed causes the calling code to not wait for the async part to complete (it actually can't wait since the method is marked async void and not async Task. You can read more about async avoid here.

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

#1


8  

If you take a look at the source code of AuthorizationFilterAttribute then you can see that the base implementation of OnAuthorizationAsync is the one actually calling OnAuthorization.

如果您查看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();
}

As you can see, you can actually override either method you want and you don't need to call the base implementation. Just choose the one which makes more since for your scenario - it doesn't matter if the controller is async or not.

如您所见,您实际上可以覆盖所需的任何方法,而无需调用基本实现。只需选择一个可以为您的场景提供更多功能的那个 - 控制器是否异步并不重要。

And regarding your question about marking OnAuthorization itself as async - the code compiles since that's the way C# async support is designed, but it indeed causes the calling code to not wait for the async part to complete (it actually can't wait since the method is marked async void and not async Task. You can read more about async avoid here.

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