Search code examples
asp.net-web-apipostsharp

Return Unauthorized result with postsharp OnMethodBoundaryAspect


I have some api actions, that I include an aspect with OnMethodBoundaryAspect, I do the validation of the token that was send in request, like this.

[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
public class TokenCallHandler : OnMethodBoundaryAspect
{
    /// <summary>
    /// Methodo responsável por validar o token enviado pelo usuário
    /// </summary>
    /// <param name="args"></param>
    public override void OnEntry(MethodExecutionArgs args)
    {
        ApiController apiController = (ApiController)args.Instance;
        var context = apiController.ControllerContext;
        HttpRequestHeaders headers = context.Request.Headers;
        bool validToken = false;
        if (headers.Contains("X-Authorization"))
        {
            var authorization = headers.GetValues("X-Authorization");
            var token = authorization.ToList().FirstOrDefault();
            if (token == null)
                token = "invalid";

            validToken = TokenUtil.ValidateToken(token);

        }

        if (!validToken)
            args.ReturnValue = new UnauthorizedAccessException();



    }

}

But it keeps going to execute the method in the api, I just want to return 401 exception.

If I do throw new UnauthorizedException it returns with 500 (internal server error) with unauthorized inside it, but I need the 401.

How can I capture in wep.api action the aspect returned?


Solution

  • As mentioned at ASP.NET Web API : Correct way to return a 401/unauthorised response,

    You should be throwing a HttpResponseException from your API method

    By setting the args.ReturnValue, you are changing the return value of the method enhanced by your aspect, but you are supposed to throw an exception instead.

    So the last line should be

    throw new HttpResponseException(HttpStatusCode.Unauthorized);

    Or, if you want to supply a custom message:

    var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Oops!!!" }; throw new HttpResponseException(msg);

    You might also consider using MethodInterceptionAspect (http://doc.postsharp.net/method-interception) as you are not wrapping the method execution, but you are intercepting it.