2

Closed

AuthorizeFilter dysfunction under async implementation

description

Implement AuthorizeFilter as following:
public class TheAuthrizeAttribute : AuthorizationFilterAttribute
{
    public async override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        var db = new MockDB();
        bool pass = await db.AsyncValidate(actionContext.Request);

        // validate;
        if (!pass)
        {
            actionContext.Response = new System.Net.Http.HttpResponseMessage(HttpStatusCode.Unauthorized);
        }
    }
}
The db.AsyncValidate return in 500 ms. However the work flow continues without waiting for its return and the Action with this AuthorizeAttribute ultimately been executed.
Closed Apr 5 at 9:49 PM by HongmeiG
It is a dup of 922. We should add an async version of IAuthorizationFilter.

comments

tugberk wrote Oct 21, 2012 at 5:59 AM

the problem is that OnAuthorization method cannot awaited by the pipeline and it will continue executing as soon as your method stops the logical execution flow on the first await. your continuation will run no matter what and you will set the actionContext.Response if the condition is met but it doesn't effect anything because the caller would have been already finished checking if the response is set or not.

The AuthorizationFilterAttribute methods are never meant to be consumed async. Use the raw interface instead as follows:
    public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(
        HttpActionContext actionContext, 
        CancellationToken cancellationToken, 
        Func<Task<HttpResponseMessage>> continuation) {

        var db = new MockDB();
        bool pass = await db.AsyncValidate(actionContext.Request);

        // validate;
        if (!pass) {
            return new System.Net.Http.HttpResponseMessage(HttpStatusCode.Unauthorized);
        }

        return await continuation();
    }

trdai wrote Oct 21, 2012 at 7:46 AM

Thanks for the comments, Tugberk.

I agree with you on the argument that AuthorizationFilterAttribute methods are never meant to be consumed async, neither does AuthorizeAttribute. In addition the OnAuthorization is actually an exception, because only method with void as return type can be overload by an async method.

However, it would be better to be addressed since the design to these two class is too easy to mislead the developers to write incorrect async implementation.

Troy

tugberk wrote Oct 21, 2012 at 10:15 AM

Ah, sorry. I didn't notice that you are a project member. I thought u were just running into issues and found this place to ask questions :)

Back to topic: I think you are right at some point but the developer, who especially writes async code with await, should be aware of the fact that any async method which returns void cannot be awaited by the caller. So, the continuation inside the void-returning async method will be sort of fire and forget unless you employ some sort of state.