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?
Related
I'm developing some small services that interact with a .net framework application. These services have UI components that require authentication and will be hosted separately, but we have a requirement to use the existing login page. I'm hoping to set up IdentityServer4 as an authorization authority, and set up the legacy application as a OIDC provider.
The problem is that I have yet to find any information on how to do that in .net framework. I can't convert the legacy application to use .net core or owin hosting, which rules out identityserver3/4 as providers. DotNetOpenAuth is not certified as a provider and does not appear to provide a standard openid interface.
What libraries or patterns can I use to solve this problem?
EDIT: after some review, what I'm mostly looking for is a middleware that would let me convert a webforms authentication to an OIDC identity.
Well.. you can start by reading http://openid.net/specs/openid-connect-core-1_0.html..
I faced the same problem a month back..
There are probably 4-6 specification documents that are dependent on this. you would have to read those as well (there is no shortcut) and you might want to start by making sequence diagrams on the get and post requests..
Amongst all this , read and implement a small jwt project which will help clear out your conception on how bearer tokens are used ( this involves how to create and validate bearer tokens)
Once you know jwt and have the sequence diagrams with you.. you can make improvisations and add more parameters..OpenId would seem relatively simpler
Also, do not forget to test your application with a third party client like postman or fiddler.
Hope this helps! All the best.
I'm fairly new to Web API and have an existing app that, by default, uses federated authentication.
However, I have one specific controller that I'd like to use either the default federated auth, or a second method that essentially uses a password sent in an HTTP header.
My initial Googling turned up stuff like this:
http://blogs.msdn.com/b/hongmeig1/archive/2012/02/27/supporting-multiple-authentication-schemes-with-web-api.aspx
...but the approach (using an HTTP module to set the HttpContext.User) seems to be universal to a site rather than targeted to a specific controller.
Plus, I'm wondering if there are more modern approaches available since the blog was written in 2012.
Can anyone help point me in the right direction?
EDIT: In further digging, it seems like I want to use an OverrideAuthenticationAttribute in conjunction with a custom authentication filter per:
What OverrideAuthenticationAttribute is for?
...but I'm trying to figure out the best way to do it (preserving default, while also adding an additional auth option).
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!
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
Is there any open source libraries for creating http based authentication like flickr and remember the milk?
http://openid.net/ is nice for public facing sites. Same sort of thing stackoverflow uses.
Otherwise it'll depend on your web development framework.
You'll be signing requests. Any OpenID or OAuth library will have code which does that - if not a separate library, something you can rip out, even though you're not using the protocol flow.
Alternately, there's demo code for Amazon AWS clients in their developer docs which also signs requests with API keys and timestamps. It's the same process on the client or server side - comparing a hash with the original - so you'll probably just have to translate their request model to whatever your framework uses.
Neither of these are exactly what you're asking for, but it's a start.