Basic Authentication with Asp.Net WebAPI

On a recent project, I undertook the task of implementing a RESTful API using the new Asp.Net WebAPI framework. The aim was to support clients of all types, including a .Net desktop app and iOS and Android mobile apps. My API had to support some sort of authentication mechanism.

Since this was a basic application (to be used as a learning tool for the other developers on our team) we decided to use Basic HTTP Authentication. As the name suggests, it’s a simple protocol whereby the client sends an authorization token as a header in the HTTP request, and the server decodes that token to decide whether or not it is valid. If it is, the request continues, otherwise it (should) return a 401 Unauthorized response.

So how can we implement this with WebAPI? With an Action Filter, of course.

The Basic Authentication Action Filter

Start by creating a new class for your filter. This must inherit from System.Web.Http.Filters.ActionFilterAttribute, which is different from the normal namespace that are used for Asp.Net MVC Action Filters. This one lives in System.Net.Http.Filters. Be careful to subclass the correct type and don’t get confused. Also, override the OnActionExecuting method:

public class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
	public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
	{
	}
}

We will use this method to intercept the API and check that everything is OK with the security side of things (well, as OK as Basic Auth can be!). First, lets check we have an authorization header:

if (actionContext.Request.Headers.Authorization == null)
{
	actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}

Simple stuff here. The fact that this action filter is executing implies that we want to protect the action that it attributes, and so if we don’t have a header, we’re not authorized.

If we have a header, lets parse the value:

else
{
	string authToken = actionContext.Request.Headers.Authorization.Parameter;
	string decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));

	string username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
	string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);
        ...
}

Just grab the header value, decode it from Base64 back to a string, and then split it. The value that is encoded would normally:, but really if this is a custom solution you can make it anything you want if you’re in control of how the value is encoded and decoded (which here I am – I just decided to follow the standard).

Now that we have the username and password, it really is up to you as to how you use it. The normal thing would be to look up some database value and check if the user exists. In my case, I grab a couple of services to find the user that the credentials refer to, and I set the user into the current principal. I then defer execution to the base filter and allow the action to run:

IPasswordTransform transform = DependencyResolver.Current.GetService<IPasswordTransform>();
IRepository<User> userRepository = DependencyResolver.Current.GetService<IRepository<User>>();

User user = userRepository.All(u => u.Username == username && u.PasswordHash == transform.Transform(password)).SingleOrDefault();

if (user != null)
{
	HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(user), new string[] { });

	base.OnActionExecuting(actionContext);
}

If the user wasn’t found, simply return a 401:

else
{
	actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}

In the code above where I set HttpContext.Current.User, I am just using a custom type called ApiIdentity, which is an implementation of IIdentity and allows me to store a user entity against the username. For brevity, it’s implementation is:

using System.Security.Principal;

public class ApiIdentity : IIdentity
{
	public User User { get; private set; }

	public ApiIdentity(User user)
	{
		if (user == null)
			throw new ArgumentNullException("user");

		this.User = user;
	}

	public string Name
	{
		get { return this.User.Username; }
	}

	public string AuthenticationType
	{
		get { return "Basic"; }
	}

	public bool IsAuthenticated
	{
		get { return true; }
	}
}

Using the Basic Authentication action filter

To use this thing, just decorate any action or controller with [BasicAuthentication], and any requests to those actions will require that the Authorization header is sent:

// GET /api/accounts
[BasicAuthentication]
public IEnumerable<OwnerAccountDto> Get()
{
	var accounts = _accountsRepository.All(a => a.OwnerKey == AuthorizedUser.Guid).ToList();

	return Mapper.Map<IEnumerable<OwnerAccountDto>>(accounts);
}

I went one step further than this and created an AuthorizedApiController which already has this attribute on it. Furthermore, I added an accessor to get the actual user entity that was authorized when the request was made:

[BasicAuthentication]
public class AuthorizedApiController : ApiController
{
public User AuthorizedUser { get { return ((ApiIdentity)HttpContext.Current.User.Identity).User; } }
}

A quick note on unit testing: having this property return something straight out of the current HttpContext instance mucks things up a little for unit testing, since there won’t be a context to look at in that scenario. The way to combat it is to either:

  • Create a provider model to retrieve the authenticated user through some IAuthenticatedUserProvider interface
  • Use a framework such as Moq to allow you to mock up a context just for this scenario (available through Nuget too)

Now you have the tools to custom-build an authentication scheme for your Web Api. Happy.. authenticating!

Articles , , , , ,

53 responses to Basic Authentication with Asp.Net WebAPI


  1. Tyrone Avnit

    Sorry if I am sounding ignorant, but is the authorization token generated on the client? If so how do you generate the token then pass it as a header in the HTTP request? Have you done this using backbone.js?

    This article is awesome, and the first time I have read an easy-to-grasp REST Authentication post. Thank you!

    Tyrone

    • Steve

      In our specific case, the server generates the auth token by encoding the concatenated username and password as Base64 (the reverse of what is described in the article) and sending it back to the client via a HTTP header when it performs their ‘log in’ action. The clients then store this auth token and send it with each subsequent request that requires it.

      If the format of the auth token is well known (as it is in my case), you could also just generate this yourself on the client and send that without having the server do this work.

      It’s a good question – I shall update the original article with this point. Thanks!

      • Nice to find such easy to follow and “get” article. Thanks Steve.
        Like Tyrone, I also need to figure how to deal with this from the client side (I must send jquery “demo’s” to the guys building the mobile client) as well as when / how to sent out those tokens.
        You mention updating an original article?
        Thanks again…going to spend some time around your blog now. ;-)

      • Hi ,
        Thanks a lot. Very good article. it was very helpful for me to implement basic authentication. I am wondering is there any possibility to keep the generated token and send it in subsequent request from client. if so really appreciate if you can provide some sample code.

        At the moment i have to send username and password for every subsequent request and authenticate.

        • Steve

          Thanks. Surely you can simply store the token locally and just write it into the headers on every request? In my implementation, the security token does not change across additional authentication requests, as it’s simply a hash of your username and password. You just need to authenticate once, then resend the same token on subsequent requests. Unfortunately I know nothing about your client, so I’d be unable to help further.

  2. Great article and well explained. Thank you!

  3. Thanigainathan

    I think base64encoding is weaker for sending passwords over http. Consider using some other encryption technology.

    • Steve

      No one is going to argue with you on that one. For a simple application posed as a learning tool, however, it’s perfectly sufficient.

  4. Pingback: Basic Authentication with Asp.Net WebAPI | Steves Coding Blog « Justin Cooney – Programming Tips

  5. Nirajan Singh

    It’s really simple and nice. Thank you very much.

  6. Quite easy to understand and informative. Thanks

  7. Mark

    Hi – this appears to solve a problem I’ve been tasked with – however, can I make a small request please? Would it be possible to provide a VS project file for this. I can’t follow where all the code should go, from the snippets above, eg the IPasswordTransform part, and the APIIdentity part. Thank you very much, Mark

    • Mark

      Hi – please ignore me – got it working just fine! Cheers, great post, and has really helped me.

      Mark

      • Steve

        No problem Mark, I just came on to comment but if you’ve already sorted it, great!

        The thing with those particular classes that you mention are really up to your solution and aren’t really a part of the Authentication per-say; I tried to get that across in the article but it could have been more clear.

  8. Fry

    Great Article.

    Just one question, excuse my ignorance, how would a javascript / jquery client perform the authentication and following requests?

    Thanks

    • Steve

      Fry,

      With jQuery/Javascript, you just need to be able to alter the headers and send along the auth token with each request. I believe jQuery.Ajax allows you to do this.

      In my solution, when actually performing authentication, we just send the username and password to the authenticate API action (as a form post, but you can also use JSON). When the response is returned, you just have to be able to read header values and retrieve the AuthToken header. If you can do those two things (read and write headers) then you should be able to do what I describe in the article.

      Bear in mind that this is just my implementation – the finer details of how the complete authentication scenario is implemented may vary from other implementations out there.

      • jShah

        Do you specific example to retrieve the AuthToken header in jQury/javascirpt and then set into headers for api requests

  9. Ashish

    Do you have a link to download the project? Thanks

    • Steve

      Hi Ashish,

      Unfortunately I don’t have a mini project to share with you. This post was derived from a much larger internal project for my organisation, which I cannot share unfortunately.

  10. paco

    Hi Steve,

    Quick question: How would you send the authorization header using the HttpClient class from .NET 4.5?

  11. Hung

    Hi Steve,
    I’m going to implement Digest Authentication into Web API, have you implemented it ?
    I see that in the class ApiIdentity you have a user type User, which .NET assembly I need to add reference or it’s just your own custom entity ?

    Thanks so much

  12. PVCR

    Hi Steve,

    I have gone through and very well explained, Could you please share how the client code code looks.

  13. Hey,

    This solution worked great. One thing I can’t get working is getting the current user. You used the controller AuthorizedApiController and called it with AuthorizedUser.Guid. This does not work for me. Could you suggest anything that I am doing wrong?

    • Steve

      How you actually query your own data source and retrieve your users is part of your own solution. Within our solution, we had a controller named AuthorizedApiController which does have some methods on it which have some helper properties on it and such. In other words, it’s not pertinent to the real point, which is to show how to achieve basic authentication within WebApi.

  14. Pingback: Blogged By Chris » Microsoft Exam 70-487 Study Guide

  15. Eric

    Great post. Very clear and exactly what I was looking for.

  16. I’ve implemented my own solution of the same problem.

    http://remy.supertext.ch/2012/04/basic-http-authorization-for-web-api-in-mvc-4-beta/

    Unfortunately, we also have the testing issue. I would rather not use Moq, but try out your IAuthenticatedUserProvider interface idea. But I’m a bit at a loss on where to start there. Could you explain this idea a little further?

    • Steve

      Hi Remy,

      This is a very simple case of Dependency Injection with Asp.Net WebApi. In the project that the excerpt in this article was taken from, we were using Ninject to inject an instance of IAuthenticatedUserProvider into our controllers, which is in turn provided to any other dependencies which need it. I have an article on Dependency Injection also on my blog and I’m sure that there are other articles which cover using Ninject with WebApi.

      It facilitates testing pretty well, because you can then just pass an instance of something which implements IAuthenticatedUserProvider which provides some meaningful data to the controllers you’re injecting into.

      Hope that helps!

  17. Glenn Graham

    Thanks for providing such a great explanation. Helped me a lot.

  18. ED

    I used Basic Authentication, but then uploaded my project to Azure only to find that Azure has Basic Authentication disabled.

  19. Pingback: Getting started with Web API, Windows Azure ACS on iOS | benpowell.org

  20. Rach

    Thanks for this article. Very useful for my implementation.

    The only addition I would add is that in the BasicAuthenticationAttribute, when the authorisation header is null, you should return the WWW-Authenticate header so the client knows to send the authentication header.

  21. Steve – great article it has been helpful. One question – why did you choose to override ‘OnActionExecuting’ as opposed to ‘OnAuthorization’ as many of the other examples doing Basic Authentication with Web API have done? Just curious if there was an explicit reason or advantage. You can see the following SO post for a description of both: asp.net mvc difference between OnAuthorization and OnActionExecuting

  22. diego

    Thanks for share this. Very nice!

  23. Pingback: ????????? ? ???????????? Microsoft. ?????, ???, ??????, ????? ????????? ?????? ?????????? ????? ? ???????? 70-487. | ???? ??????????????? ??????????

  24. This a very good post, I just want to know how should be the client ajax call for this kind of authentication?

    Tks

  25. Pingback: User Authentication in ASP.NET Web API | Ask Programming & Technology

  26. Pingback: Meu guia de estudos para o Exam 70-487 Developing Windows Azure and Web Services | Vitor Meriat

  27. Tuan Jinn Nguyen

    Awesome article, great and simple explanation. I did almost exactly the same thing, but a bit reversed (the authentication token is sent back upon the “Login” action – which similar to one of your answer to some question here). I have a bit more complicated authorization process which uses roles etc. Thanks!

  28. Kaan

    I would be very happy if you could provide the source code.

  29. Pingback: Authentication and authorization , Stackoverflow reference(http://stackoverflow.com/questions/11731683/user-authentication-in-asp-net-web-api) | Dive into the pool of technology

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>