0

I am uploading files using ng-file-upload and having some abnormal problem as the HttpContext.Current is null when using the IAuthenticationFilter. While everything working correctly when I comment the authentication filter in WebApiConfig.

Controller to Test

    [HttpPost]
    public IHttpActionResult Upload()
    {
        var current = HttpContext.Current;
        if (current == null)
        {
            return Content(HttpStatusCode.BadRequest, Logger.Error("HttpContext.Current is null"));
        }            

        if (current.Request != null && current.Request.Files != null)
        {
            var file = current.Request.Files.Count > 0 ? current.Request.Files[0] : null;
            if (file != null)
            {
                file.SaveAs(@"C:\Temp\test.csv");
            }
        }
        return Content(HttpStatusCode.BadRequest, Logger.Error("Should not reach here"));
    }

IAuthenticationFilter

public class KeyAuthentication : Attribute, IAuthenticationFilter
{
    // we only want to apply our authentication filter once on a controller or action method so return false:
    public bool AllowMultiple
    {
        get { return false; }
    }

    // Authenticate the user by apiKey
    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {            
        HttpRequestMessage request = context.Request;

        string apiKey = ExtractApiKey(request);
        bool IsValidCustomer = await ValidateKey(apiKey);
        if (IsValidCustomer)
        {
            var currentPrincipal = new GenericPrincipal(new GenericIdentity(apiKey), null);
            context.Principal = principal;                
        }
        else
        {
             context.ErrorResult = new ErrorMessageResult("Missing API Key");
        }
    }

    // We don't want to add challange as I am using keys authenticaiton
    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {  
        return Task.FromResult(0);
    }
}

Extract API Key

public static string ExtractApiKey(HttpRequestMessage request)
{
    if (!request.Headers.TryGetValues("x-api-key", out IEnumerable<string> keys))
return string.Empty;

    return keys.First();
}
Priyanka Rathee
  • 1,077
  • 2
  • 13
  • 19
  • Don't use or couple your code to `HttpContext.Current`. If this is an `ApiController` you need to change the approach used. – Nkosi Oct 21 '18 at 11:37
  • How is the file being posted from the client – Nkosi Oct 21 '18 at 11:49
  • Could you please share the `ExtractApiKey` method? I am going to bet you have pulled the request body in that method -- this will cause the request body to become `null` as it moves to the next handler in the request pipeline. – Svek Oct 22 '18 at 10:38
  • @Svek No, I am just extracting the header. Updated the code above. Found something interesting, The code is working fine if I remove the "async" from AuthenticateAsync method. So, it seems the IIS is changing it's thread the HttpContext lost somewhere in between. While have everything there when not using async/await. – Priyanka Rathee Oct 22 '18 at 11:22
  • Actually, where is your `await` in the method? Usually, you would have a statement like `IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);` – Svek Oct 22 '18 at 11:33
  • Also, as noted earlier, probably should not be using `HttpContext.Current` see here https://stackoverflow.com/a/38574489/3645638 – Svek Oct 22 '18 at 11:39
  • Possible duplicate, see https://stackoverflow.com/a/32338414/3973463 – Alfredo A. Oct 22 '18 at 14:28

1 Answers1

0

The solution was to include "targetFramework=4.5" in the web.config as commented by @Alfredo and more details in https://stackoverflow.com/a/32338414/3973463

Priyanka Rathee
  • 1,077
  • 2
  • 13
  • 19