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!

56 thoughts on “Basic Authentication with Asp.Net WebAPI

  1. 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

    1. 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!

      1. 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. ;-)

      2. 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.

        1. 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.

      3. That sounds insecure! If someone can determine in advance what the token will be they can simply construe one themselves! The Token should be a cryptographically secure random generated value.

        1. You’re right, it should be. The actual generation of the token is not the focus of this article and you should take steps to provide a secure token in your own implementation.

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

    1. 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.

  3. 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

      1. 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.

  4. Great Article.

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

    Thanks

    1. 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.

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

    1. 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.

  5. 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

    1. Hi,

      I haven’t implemented it, no. The User entity is completely born out of my own solution, and simply exists to serve as a convenient reference to the current user object from my database, which is retrieved using the authentication credentials. How you implement this (or indeed, whether or not you even need it) is entirely up to you.

  6. 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?

    1. 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.

    1. 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!

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

  8. 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.

  9. 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!

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>