0
votes

This a .NET 4.5 C# MVC + WebAPI 4 project. I am using the WebApiDoodle 2.0.1 BasicAuthenticationHandler to use MVC + WebAPI side by side security as explained here.

In my Application Start I add the Message Handler:

globalConfig.MessageHandlers.Add(new {MyClass Derived from BasicAuthenticationHandler}());

The MVC controllers work fine (classes derived from System.Web.Mvc.Controller).

However, the WebApi controllers (derived from System.Web.Http.ApiController) ignore the System.Web.Http.AllowAnonymous attribute. They basically want to authenticate/authorize everything.

If I remove the custom message handler from the globalConfig the WebAPI works as expected, the AllowAnonymous attribute allows anonymous requests to be served (and actions that have [Authorize] are denied).

Any ideas what might be happening? Thanks.

2

2 Answers

0
votes

It's look like a bug in that MessageHandler

https://github.com/WebAPIDoodle/WebAPIDoodle/blob/dev/src/WebApiDoodle.Web/MessageHandlers/BasicAuthenticationHandler.cs

If Authorization header is null, it's returning a challenge (www-challenge), so it never invokes the Web API. The challenge should only be returned if the web api method can not be executed because it requires authorization. It should have something like this,

    return base.SendAsync(request, cancellationToken)
.ContinueWith<HttpResponseMessage>(r =>
{
  if (r.Result.StatusCode == HttpStatusCode.Unauthorized)
  {
    return HandleUnauthenticatedRequestImpl(request, cancellationToken);
  }

  return r.Result;
}); 

Ask the project owner if he can fix the handler.

0
votes

After discussing with the developer of WebApiDoodle he suggested a different approach.

You can see detail of the discussion here: https://github.com/WebAPIDoodle/WebAPIDoodle/pull/8

Anyways, the important part from the developer:

AllowAnonymousAttribute has no logic inside it. AuthorizeAttribute honors it. In my personal opinion, every user should authenticate to an API if that API needs authentication. That's why u see this as the default behavior. However, the fix is easy. Just override HandleUnauthenticatedRequest method and keep it empty. Then, add the challenge request as a continuation to your handler's SendAsync method just like you did.