Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

authentication filter: How to do a HTTP 401 with message

I followed http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/ to do a custom authentication filter.

Everything is working correctly but I cannot get the server to say anything upon a 401. It correctly gives the www-authenicate header and status code 401 but no content/body.

I tried using AuthenticationFailureResult the from http://www.asp.net/web-api/overview/security/authentication-filters but did not help. I converted my AuthenticateAsync to async and ignored the await warning.

This is my current work around, the code in comments is what I -wish- I could do, that is mostly have it use whatever formatter

//request.CreateResponse(HttpStatusCode.Unauthorized, new { Error = true, Message = "Token is invalid" });
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write("{ \"Error\" = true, \"Message\" = \"Token is invalid\" }");
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], request);
like image 595
ParoX Avatar asked Sep 24 '15 19:09

ParoX


People also ask

How do I create a custom authentication filter?

In order to create a Custom Authentication filter in MVC, you need to create a class by implementing the IAuthenticationFilter Interface. This IAuthenticationFilter interface has 2 methods. Following is the class definition of the IAuthenticationFilter interface.

How do I use authorization filter in Web API?

Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action. You can apply the filter globally, at the controller level, or at the level of individual actions.

How do I provide authentication in Web API?

To access the web API method, we have to pass the user credentials in the request header. If we do not pass the user credentials in the request header, then the server returns 401 (unauthorized) status code indicating the server supports Basic Authentication.

How does authentication and authorization work in Web API?

The authentication and authorization mechanism in such a site is simple. After the user logs into the website, a single database holding user information verifies their identity. A session is created on the server, and all subsequent requests use the session to identify the user without another login required.


1 Answers

There two options to do this: quick but brute and longer but more elegant

A. Modify HttpResponse directly:

HttpContext.Current.Response.StatusCode = 401;
HttpContext.Current.Response.Write("some content");

B. Implement IHttpActionResult and set a Content property of a HttpResponseMessage in that class:

public class AuthenticationFailureResult : IHttpActionResult
{
    public AuthenticationFailureResult(object jsonContent, HttpRequestMessage request)
    {
        JsonContent = jsonContent;
        Request = request;
    }

    public HttpRequestMessage Request { get; private set; }

    public Object JsonContent { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(Execute());
    }

    private HttpResponseMessage Execute()
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        response.RequestMessage = Request;
        response.Content = new ObjectContent(JsonContent.GetType(), JsonContent, new JsonMediaTypeFormatter());
        return response;
    }
}

Then you'll be able to use it like this:

context.ErrorResult = new AuthenticationFailureResult(new { Error = true, Message = "Token is invalid" }, request);

Note: If you want to use anonymous types for JsonContent make sure that AuthenticationFailureResult implemented in the same library.

like image 79
Vova Avatar answered Oct 17 '22 00:10

Vova