I'm in the process of migrating a rather extensive REST service from WCF to ASP.NET WebAPI. We are using the Authorization header to send tokens from client to the server, and I implemented a DelegateHandler with code that responds with a 401 as soon as it sees there is no valid Authorization header. A simplification of the code can be seen here:
public class AuthenticationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null) throw new ArgumentNullException("request");
return !IsClientAuthorized(request)
? Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.Unauthorized))
: base.SendAsync(request, cancellationToken);
}
private bool IsClientAuthorized(HttpRequestMessage request)
{
return request != null && !string.IsNullOrEmpty(request.Headers.Authorization.ToString());
}
}
It works fine when hosted in IIS, but for integration tests I am using HttpSelfHostServer, and here the Authorization header is not present on the HttpRequestMessage, even though I can see it was sent on the Fiddler trace.
I tried to make a really simple WebAPI application using self hosting to verify that the problem is consistent, but unfortunately it works as expected there. So it must be related to my code somehow, but I am completely blank to what is causing it.
Has anyone else seen this behavior, or does anyone have suggestions for how to trace where in the WebAPI stack it goes wrong?
The problem turned out to be caused by the format of the Authorization header being sent. We would expect the Authorization header to look something like this:
This worked fine under WCF, but it is not formatted according to the HTTP standard, which expects a scheme and a value. For example:
My guess is that with only the value in the header, Web API would regard this as the scheme, and only certain characters are allowed in here. When I added XAPI as the scheme and used the same value everything worked fine, and the Authorization header was available to my code on HttpRequestMessage.Headers.Authorization.
However I think it is a bug in Web API, that the request is allowed to proceed and the header is just ignored, if it had an invalid format. I would expect it to respond with a 400 Bad Request if a header was invalid according to specification.