Authenticating REST requests in MVC 2 - c#

Hey SO, in the past few hours I was trying to get my head around RESTful services that can be served via asp.net MVC. Authentication is still something that doesn't seem to be covered in all those tutorials and guides i was finding in the interwebs.
Currently we are using Forms Based Authentication in our existing MVC Application. As far as I understand we need to add Basic HTTP Authentication to be able to handle REST requests and user permissions connected to the user context. Is there any way to "mix" these two Authentication Modes in one Application?

I'm not sure if there's anything built in, but you can write your own. Something like:
var authHeader = Request.ServerVariables["HTTP_AUTHORIZATION"];
if (authHeader.StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
{
var authParams = Encoding.Default.GetString(Convert.FromBase64String(authHeader.Substring("Basic ".Length)));
var arr = authParams.Split(':');
var username = arr[0];
var password = arr[1];
}
If you're writing your own REST framework in MVC, you could have a base Controller class, and have a method similar to this that runs before each action to authenticate the caller.

Dave,
I understand your point. Membership framework uses cookie extensively for authentication. You pass your credentials to server, server validates them against user database and issue you an authentication cookie. Next time every call of urs contains this authentication cookie which server uses to authenticate and authorise the user. Now whole this workflow works seamlessly when you use browsers.
Now in your scenario, you can create an Action in a controller which validates credentials. You can pass credentials to this Action in either post/get data. You will have to save the authentication cookie in your code and include that each time when making a call to the server . You can override HttpWebRequest class to perform these steps and you can use same class in your code.
In case this is much of an overhead and you are looking for something like Web-Services sort of functionality, I will advice you to look into WCF Services / Ado.NET Data Services. These integrate with Membership framework more seamlessly and may be better suited to your results.
I hope this helps, thanks.

You can easily use ASP.NET membership framework with ASP.NET MVC RESTful services. See the following link for its implementation with MVC RESTful services.
http://msdn.microsoft.com/en-us/magazine/dd943053.aspx
In case you are not aware of membership framework use following link
http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
I hope it helps, thanks

Related

Call external Web API from MVC project with windows Auth

I have an existing MVC application that I inherited from someone else.
I am now trying to take some of the API calls from the old application and move them into a new application.
The problem is, when the MVC application tries to call the API calls in the new application, it gets a 401.2 (unauthorised) response.
I have read that 401.2 means that the front end and the back end are using different authentication protocols, which would make sense to me.
Here is a snip of the response headers for the account call in the new application:
and here is a snip of the same response headers when calling the same API from the old application:
This looks to me like they are using different protocols - am I correct? The main difference seems to be the 'WWW-Authenticate:Negotiate' on the failed request - but I do not know how I can fix this?
If so, can anyone advise what I need to change in my MVC project to make it use the Auth type of the first project?
Both aps use the same database if that is any help?
I know this question is a bit vague, but I have no idea where to look to fix this.
Any help would be greatly appreciated...
You would need a Single Sign-on to maintain your credentials through different apps, you could:
Use Identity Server 4 or Identity Server 3 To generate token credentials for you WEB API Projects.
MVC
JS
User Forms authentication on your mvc Projects:
Example
Use cookie based Authorization:
Cookie authorization with OWIN
I recommend Using Identity Server.

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?
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.
Depending on which version you are using. MVC5 Web API 2 implements an approach called bearer tokens. So you basically execute a post with username and password upfront to your https://applicationhostlocation/token endpoint. This will return a bearer token in the payload. You send subsequent https requests to your authorized web api methods with the bearer token in a header. This is all out of the box with the latest version of the web api. This link outlines the approach pretty well: http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
Custom Membership Provider my friend!
https://codeutil.wordpress.com/2013/05/14/forms-authentication-in-asp-net-mvc-4/
With custom membership provider You can set a Authorization Cookie Token (aka AuthCookie), and use the Forms Authentication technology in your application. With a Custom Membership Provider, You'll be able to create a custom Validation Method that access your DataBase to match users credentials.
With the AuthCookie, every subsequent request will be authenticated, like a traditional Authorization Cookie technology.
Also, you can use a rewrite Url approach to enforce users to be redirected to the SSL pages: Best way in asp.net to force https for an entire site?

Using an MVC Controller as proxy between the client and the Web API

I am trying to develop a single page application.
I have built a RESTful web service using ASP.NET Web API. I have implemented authentication using OAuth 2.0 and Bearer access tokens.
This web service uses memcached and HTTP cache headers (Cache-Control and ETag) for caching the resources and responses.
Now, I really like ASP.NET MVC technology and maybe that love is making me use it when I shouldn't.
I'm thinking of builidng an MVC intermediate server between my JavaScript application and my Web service.
The MVC site would redirect (or delegate) its requests, to the Web Service.
I see many advantages using this approach:
I can store my consumer key (used for authentication) in a secure location, as opposed to storing it in the JavaScript application directly.
I can provide cookies to my JavaScript application, something that my REST web service does not support (because I think it ruins the whole "stateless" and "Pure HTTP" concept.
It would be very easy for me to provide globalization (localization) to my views. I really like ASP.NET MVC globalization framework and I would not know how to add this feature if I plan to create a standalone site.
I can encrypt my access token cookie, and decrypt it on the server, forcing my user to use my MVC proxy to access the web service, as he will not know his access token.
Having stated these advantages, would it be worth it to implement this?
Adding a proxy server will made me replicate the HTTP cache logic, and will also end up creating 2 requests (Client -> MVC -> Web API) instead of 1 (Client -> Web API).
What is the best approach?
It looks like you've built a good RESTful web service, but need to address Auth and Globalization:
Auth
Having this kind of proxy or support cookie authentication on the Web API will make you vulnerable to CSRF attacks, so you would also need to implement Synchronizer Token Pattern or some other technique to prevent this. However you should only use this approach if you have no other options, but you have!
Assuming javascript application requires user to enter credentials, there are different ways to deal with auth for it:
OAuth2 Resource Owner Password Credentials Grant
JSON Web Tokens - see accompanying website and a specification
Both ways provide your JS app with an encrypted token that it should pass with each call to protected API. Your application would need to keep this token in a local storage and refresh it when token expires.
Globalization
Even having most of the things on MVC side, eventually you would still require Web API to deliver translated content. So I'm not sure what are the requirements here, but generally speaking you should be able to get your translated resources on Web API the same way. See here for example.
For the HTML part - leave it to ASP.NET MVC, no need to put every label translation into API.
Another points to consider
Performance - ASP.NET MVC is good, but it's not a proxy solution and it's simply not intended to build things like that
Do you really need an HTTP API?
Don't forget that transferring data over HTTP is another point of overhead, and it becomes especially useless if you proxy it with and MVC.
At the end of the day - why would you build an API if you are hiding it from your own application?
My answer is: don't hide it - make full use of it!

Custom authorization i asp.net web api

I have a project which uses both Web Api and MVC. The authentication is handled by FormsAuthentication, which creates a cookie containing some data regarding the user.
I have extended System.Web.Mvc.AuthorizeAttribute and added it to every MVC controller. What it does is extend AuthorizeCore and check to content of the cookie, which is my own extension of IPrinciple, for wether the user currently has limited access.
I would like to do a similar check for calls to my Web Api, so i have made an extension for System.Web.Http.AuthorizeAttribute which overrides the IsAuthorized method.
In this method i would like to make the same check as for the controller, but i don't know how to get the information from the cookie or if this is even the proper way to do this.
In general using cookie authentication in web api is not recommended.
The reason is that cookies are handled well only in browsers The whole concept of web api is to allow other clients (native clients, java script ...) to use it as well.
If you sure that your server is going to be accessed from browser only maybe you should move your api actions to MVC project (it could return json / xml as well). This way you will not have to deal with those kind of issues.
For web api I would recommend using token based authentication

How do I access my own API from my MVC site?

here's my setup:
I have an MVC3 site hosted with a www subdomain (e.g., www.example.com). My site is secured via SSL and forms authentication, backed by ASP.NET membership/role providers. I have HTTP handlers providing service capabilities under /services (e.g., www.example.com/services). These are secured through Basic authentication over SSL. I have mobile devices successfully accessing/consuming these services. I have also created a new site with an api subdomain (e.g., api.example.com) that will be my public-facing API. These services are exposed currently via WCF Web API preview 6 (eventually to be migrated to ASP.NET Web API). These services are also secured via Basic authentication over SSL. My ASP.NET membership implementation stores hashed passwords (i.e., they are not encrypted). All services serve JSON responses. All of this stuff works great.
Here's my dilemma:
I started to write a new view on the MVC site and realized it would be great to use Ajax. My specific case is to implement cascading drop-down lists. I wanted to implement this using jQuery and a new service under the api subdomain. At first I thought this would be a simple exercise and then I realized, I have no effective way to call into my own API. My clients (mobile devices) all store their username/passwords locally so this is easy. However, if the same user is logged into my site, I have their username but not their password so I do not have a direct way to access any services offered under the api subdomain.
As I see it, I have three solutions:
Implement services that support the MVC site directly under the /services URI, eschewing consuming my own public API.
Create a super user in my membership store (where I know the username/password) that the site uses to access services in the api subdomain.
Change my authentication strategy.
It occurs to me that I probably should not utilize my own public API and would be better served using my own private services (which is ok because the logic is all shared via a facade layer).
What is the recommended strategy here? I also assume that if I were to utilize option 2 or 3, I would have to do so using JSONP. Is this correct?
Any advice would be greatly appreciated. And if more details are needed, please post and I will update with answers.
Thanks!
If Im following this correctly, you simply need to make sure your Forms Auth cookie is written with no subdomain so it would be: .example.com and if you are using separate servers, you share your machine key across them.
Since forms auth tokens are stateless and nothing is kept on the server side, this should work fine.
For simplicity and because I decided it was not in my best interest to consume my own public API, I implemented JsonResult actions on a new controller in the existing MVC site. This allowed me to utilize the existing forms authentication and avoid the cross-domain ajax requests.

Categories

Resources