views:

337

answers:

4

Hi,

I'd like to implement a REST api to an existing ASP.NET MVC website. I've managed to set up WCF Data services so that I can browse my data, but now the question is how to handle authentication.

Right now the data service is secured via the site's built in forms authentication, and that's ok when accessing the service from AJAX forms. However, It's not ideal for a RESTful api.

What I would like as an alternative to forms authentication is for the users to simply embed the user name and password into the url to the web service or as request parameters.

For example, if my web service is usually accessible as

http://localhost:1234/api.svc

I'd like to be able to access it using the url

http://localhost:1234/api.svc/{login}/{password}

So, my questions are as follows:

  • Is this a sane approach?

  • If yes, how can I implement this? It seems trivial redirecting GET requests so that the login and password are attached as GET parameters. I also know how to inspect the http context and use those parameters to filter the results. But I am not sure if / how the same approach could be applied to POST, PUT and DELETE requests. Can I use GET parameters in POST, PUT and DELETE requests?

Thanks,

Adrian

Edit: The question for me how to embed login and password into the web service's URL so that I can perform POST, PUT and DELETE requests against the web service. I do know how to implement authentication once the web service is running and the login / password are contained somewhere in the HTTPContext. Also, I am not looking for ways to implement forms or basic authentication. I know how to do it, but it is not what I am looking for.

A: 

adrian,

i've not had to use restful via authentication but i do have to ensure that groups of users have the rights to access the rest service. this i do via an md5 token that get's passed to the web service (this is a normal json service, not a wcf wrapper). basically, i 'know' which websites are allowed access to my service, so i give them their own api key (which for simplicity is an md5 of the domain name. this get's checked incoming by a filter against the urlreferrer and if the md5 of that matches, then it's go.

I know this isn't the authentication answer, but it's a mid-trust approach that works if you need only a very course level of 'authentication'.

i'd be interest3ed to see how others do do this tho for other projects that i may need a less course grained approach to authentication.

jim

jim
Jim, Thanks for your reply. I am not sure if I understand your answer correctly, but it doesn't really matter whether you are using a token or a login / password combination. For me the question is how to embed this information into the web service's URL so that I can perform POST, PUT and DELETE requests. If you have any ideas on that, please le me know!
Adrian Grigore
adrian,i'm embedding a json object in the POST requests, so it never 'touches' the url as such.
jim
ah, I see. Are you using odata or your own implementation? If it's odata, I'd like to know how you have solved embedding the credentials on the client side.
Adrian Grigore
adrian, i'm actually using the service via jquery. the user sites are given their API keys and this is plumbed into the json parameters (in the ajax call) along the lines of: var params = {apiKey: "942B24BC140A4920B200A5F79C4E5D9D"}. so when the ajax call is made, this is then validated in the controller. as i said, it's very course grained and it may be too high up the chain for your requirement. but it works very well for me. also, the fact that the apiKey identifies the user domain means that should i want to, i can taylor the results per domain. a kind of domain priviledges if you like.
jim
also, as it's cross -domain, it is of course jsonp.
jim
A: 

OData - WCF Data Services Best Practices from TechEd - Meta-Me - Site Home - MSDN Blogs

<system.web.extensions>
  <scripting>
    <webServices>
       <authenticationService enabled="true" />
    </webServices>
  </scripting>
</system.web.extensions>

How about this?

takepara
takepara - that would definately be required, tho i have a feeling that adrian is looking for solutions to the mvc authentication implementation, rather than configuration settings.
jim
Thanks for your reply, but this is not what I am looking for. It would be perfect if I was the only one coding against the API. However, since I want third party developers to code their own clients for my application, I need to implement an API that is as simple to code against (from any platform, not just the ones covered by odata clients) as possible.
Adrian Grigore
A: 

See if below answers helps you:

your first question:

•Is this a sane approach?

If your service is running over https, I dont see any probelm to use this method.

•If yes, how can I implement this? It seems trivial redirecting GET requests so that the login and password are attached as GET parameters. I also know how to inspect the http context and use those parameters to filter the results. But I am not sure if / how the same approach could be applied to POST, PUT and DELETE requests. Can I use GET parameters in POST, PUT and DELETE requests?

You can use GET parameters in your other methods eg. Here stream is passed in body.

[OperationContract]
        [WebInvoke(Method="POST", UriTemplate = "UploadFile/{fileName}/{userToken}")]
        string UploadFile(string fileName,string userToken,Stream fileContents);
lucene user
Are you perhaps referring to WCF? This post is about WCF Data services, which is something completely different.
Adrian Grigore
A: 

In the end I used a threefold approach, either of these authentication methods work fine on my data service:

  • Basic authentication with the API key as password
  • Authentication via an API key embedded as request header
  • URL-based authentication with the API key as path to the API. I implemented this with a proxy ASP.NET MVC controller.
Adrian Grigore