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.