Search code examples
c#asp.netasp.net-web-api

ASP.NET Web API with custom authentication


I am looking for help creating a Web API with custom username/password authentication.

I have my own database to validate users against, I do not want to use windows authentication.

I am hoping to be able to decorate my web api calls with an attribute like [Authorize], so that calls made without logging in will fail.

I do not want to have to pass credentials as a parameter to every method.

This API is going to be consumed primarily by mobile devices using Xamarin PCL.

The web API must use SSL.

This seems like a simple setup yet my googling does not reveal any super useful hits.

Ideally I'd want a Login controller that authorizes a user and allows subsequent method calls through.

Can someone provide a basic example or some good reading material?


Solution

  • It's a big subject and you probably need to spend some time boning up on the basics, sorry.

    That said... In order for subsequent method calls to be authenticated, you need something that can be passed back with every request. If you are calling your api from a website, say because you are using Angular or similar, then a simple cookie (appropriately encrypted and MACed) will work. Exactly how to implement that depends on whether you are using OWIN or not and whether you also have MVC in your project to serve up your pages. Don't create the cookie yourself, use FormsAuthentication or the equivalent OWIN middleware. You don't need to use Microsofts Membership or Identity, but be aware that doing your own password handling is not trivial and you really need to know what you are doing with that stuff - there is no substitute for a lot of research if you want to do that.

    If you need to call the api from something other than a Web site, then a cookie is painful. Also be mindful that there are some subtle CSRF vulnerabilities when using cookies and Web api that you need to understand and protect against.

    An alternative to cookies is to embed something like ThinkTecture Identityserver (it's free) and use that to issue oAuth tokens and then attach them to each API request. It has a number of advantages but is also more complex.

    Resources
    You did ask for pointers on where to start reading. Your task is complicated by the fact that Microsoft has been changing their "default" approach to it several times over the last few years. The current default approach is Identity which replaces the previous MembershipProvider (good riddance). If you are new to this, I'd suggest you go that route to be honest - you can extend it and it ties in with most of the rest of the stack very nicely. Yes, you lose some flexibility and you need to wrap it around your current user store. But you need to ask yourself if the security you get out of the box isn't worth that.

    I would also recommend Brock Allen's blog. It's pretty hardcore but he knows his stuff and will often explain the innards of a lot of Microsoft authentication technologies.

    I would recommend you try to read up on "OWIN Authentication Middleware". It's where it is all going, not least with ASP.Net vNext. Sadly, most of the documentation out there focus on how super easy it is to use (and it is - for a demo) but lack any in-depth info about how it really works, which can be very frustrating.

    In order to get to grips with how tokens and the different standards work, I would recommend you watch this video here: http://www.ndcvideos.com/#/app/video/2651

    Then look at Azure Mobile Services which has even got client-side libraries for handling the auth I believe or ThinkTecture Identity Server. Even if you end up not using IdSrv, by going through their tutorials on how to use it, you will learn an awful lot about how this whole thing works in general; it's all based on open standards. Docs here: http://identityserver.github.io/Documentation/docs/ Try working through their tutorials; They use a windows console app in place of an app, but the concept is the same.

    I wish you luck but would like to just close by saying please don't just hack something together that seems to work. Web security is increasingly complex and it is very easy to leave vulnerabilities in your code - I talk from experience :)

    Don't be a Moonpig.