ASP.NET Web API Authentication Options

What options are available for authenticating the MVC3 Web API application that should be used by a jQuery application from another domain?

Here are the limitations I've tried so far: -

  • I do not want to use OAuth; for private applications with limited user bases, I cannot expect end users to have their own accounts with an existing provider, and there is no way to implement my own
  • I had a fully functional HMAC-SHA256 implementation that worked just fine, using the data passed in the headers; but this does not work in IE because CORS in IE8 / 9 is broken and does not allow sending headers.
  • I need a cross-domain because the consumer application is in a different API domain but cannot use jsonp because it does not allow the use of headers.
  • I would like to avoid the token based approach (only) as it is open to replay and violates REST while maintaining state

At this point, I came to terms with the HMAC-SHA256 approach, which uses either a URL or a query / post string to provide a hash and other variables.

Putting these variables in the url seems just dirty, and putting them in the query string / message is a pain.

I have successfully used the JQuery $ .ajaxSetup beforeSend parameter to generate a hash and attach it to the headers, but as I said, you cannot use headers with IE8 / 9.

Now I had to resort to $ .ajaxPrefilter because I cannot change the ajax data in beforeSend and cannot just expand the data in $ .ajaxSetup because I need to dynamically calculate the hash values ​​based on the ajax request type. $ .ajaxPrefilter is also a problem because there is no clean / easy way to add the necessary variables in such a way that it is an agnostic method ... that is, it should be querystring for GET and formdata for POST

Something is missing for me, because I just can’t find a solution that: a) supports cross-domain a) not massive hacking on both sides of MVC and JQuery c) actually provide d) works with IE8 / 9

There must be someone doing it right ...

EDIT

To clarify, the authentication mechanism on the API side is fine ... no matter how I validate the request, I generate a GenericPrincipal and use it in the API (essentially this is for a different message, but it allows me to use standard authorization mechanisms in MVC that I prefer rewinding on my own ... less for other developers on my API to learn and maintain)

The problem is primarily the transfer of authentication information from the client to the API: - - It cannot rely on the status of the server / API. Therefore, I can’t transfer the username / password in one call, get the token back, and then continue to use this token (open for re-attack) - Everything that requires the use of request headers is missing, because IE uses XDR instead of XHR, like other browsers, and it does not support custom headers (I know that IE10 supports XHR, but I really need IE8 + support) - I think I'm stuck by creating HMAC and passing it to the URL somewhere (path or request), but it seems like a hack because i use parts of the request and not intended for this - If I use the way, there are a lot of indiscriminate indiscriminately, because at least I need a username, time stamp and hash with each request; they need to be differentiated somehow, and I have little control over the delimiters used in the rest of the URL - If I use data (querystring / formdata), I need to change the place where I send my authentication data depending on the method that I use (formdata for POST / PUT / etc and querystring for GET), and I also allow the application level data space with these vars

However bad the querystring / formdata seems to be the best option; however, now I need to figure out how to fix them for each request. I can use MessageHandler or Filter, but none of them provide a convenient way to access formdata.

I know that I can simply write all the parses and process things (and it looks like I will), but I cannot believe that this is no longer a solution. I like (1) IE support, (2) safe and (3) clean code, and I can only choose two.

+4
source share
2 answers

Your requirements seem a little unjustified to me. You can never have everything at the same time; you must be prepared to say something. A few notes:

  • OAuth looks like what you want here, at least with some changes. You can use the Azure Access Control Service so you don’t have to implement your own token provider. Thus, you “outsourced” the implementation of a secure token provider. The last thing I checked, Azure ACS was still free. When you are looking for ACS documentation, there is a lot of confusion because people mostly use it to connect to another provider like Facebook or Google, but you can configure it to be a token provider for your own services.
  • You seem to worry a lot about repeated attacks. Repeated attacks are almost always possible. I should just listen to the data transmitting the wire and send it to your server, even through SSL. Repeat attacks are what you need to deal with independently. Usually, I track the cache of incoming requests and add a hash signature to my cache. If I see another request with the same hash for 5 minutes, I ignore it. For this to work, I add the timestamp (millisecond granularity) of the request and some derivative of the URL as hash parameters. This allows one operation per millisecond to the same address from the same client without a request marked as a re-attack.
  • You mentioned jQuery, which puzzles me a bit if you use the hash method. This would mean that you actually have a hash algorithm and client signature logic. This is a serious flaw, because just by checking javascript, now I can know exactly how to sign the request and send it to your server.
+3
source

Just said; ASP.NET WebAPI doesn’t make much sense when it comes to authentication.

I can say that if you host it inside ASP.NET, you will get ASP.NET support for authentication and authorization. If you choose to host yourself, you will have the option to enable WCF binding security settings.

When you host your WebAPI in ASP.NET, you will have several authentication options:

  • Basic Authentication
  • Form authentication - for example. from any ASP.Net project, you can enable Authentication_JSON_AppService.axd for forms authentication.
  • Windows Authentication - HttpClient / WebHttpRequest / WebClient
  • Or explicitly allow anonymous access to your WebAPI method
+1
source

All Articles