I have my authentication logic in a class, derived from System.Web.Http.AuthorizeAttribute (overridden OnAuthorization method). I make a call to a DB from that method and I want that call to be asynchronous (luckily, the new ADO.NET async API allows that).
Then I apply this attribute to a controller to have all calls to it go thru the authentication filter. So far so good.
But doing so I run into the following problem. The framework (ASP.NET Web API) doesn't seem to be aware of what my intentions are :) It looks like it proceeds with the controller's action execution before my filter's OnAuthorizaion methods finishes (returns from the async call).. Hence the exception from the framework a la "request processing finished before all the outstanding async operations are complete.."
Is there any out-of-the-box way to deal with that?
P.S. My gut feeling says that I'm in for a custom action filter creation.. Then I'll need to override ExecuteActionFilterAsync and do my authentication there handling all the Task-related stuff myself with no help from the framework side.. )
Use IAsyncAuthorizationFilter
and implement the interface asynchronously.
public async Task OnAuthorizationAsync(AuthorizationFilterContext actionContext)
Ok, here is what I came up with (after taking a peek under the hood with reflector):
public class SecurityFilterAttribute : FilterAttribute, IAuthorizationFilter
{
public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
await OnAuthentication(actionContext);
return actionContext.Response ?? await continuation();
}
private async Task OnAuthentication(HttpActionContext actionContext)
{
//some lengthy I/O operations (XXXAsync/await)
}
}
This way, being applied to a controller/action, all the logic will be executed in proper order while keeping the thread unblocked during I/O. Not very respectful to cancellation, though. But should be okay for my purposes..
Anyway, I really wonder what made Web API creators not to go similar way... Ideas?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With