Using OAuth in .net without Membership
If you search for anything to do with OAuth (Open Authorization), you’ll find lots of very comprehensive examples of how to get started using OAuth in .net 4.5 and VS2013 from the in built templates. You’ll also find a few .net 4.0 examples which also show you how to get started with OAuth, but pretty much everything described is tightly couples with asp.net membership. If, like me, you’re working on a project that uses its own authentication and authorization implementation, or you simply don’t want to take a dependency on a database of any kind, then the information is harder to get hold of.
What is OAuth?
At its simplest, OAuth allows you to log in to one site (site A) using your credentials from another site (site B) without ever providing your details to site A. This is beneficial for a number of reasons:
- Fewer credentials to remember for the user
- The hosting site doesn’t need to concern itself with handling this kind of sensitive data
- Rich profile information can be obtained (if permitted), enhancing the user experience
- Allows the user control over which sites can authenticate them and they can revoke this control at any time
Many of the largest websites on the internet either offer OAuth login functionality (including the likes of StackOverflow, Vimeo, Digg, Disqus, Tripadvisor etc), or act as a provider (e.g. Facebook, Microsoft, Google, Yahoo, LinkedIn etc). It’s pretty safe to say, if you’ve logged in to any other site using your Facebook account, you’ve used OAuth.
Lets get started
In the following example I’ll be using VS2013, but VS2012 should also work just fine.
- Create a new solution in Visual Studio:
- File->New->VisualC#->Web->ASP.NET Web Application
- Be sure to select Empty Web Application for the template and notice that Authentication is set to no authentication
- Once the project has been created, open up NuGet (right-click on References and select ‘manage NuGet packages’) and search for the Microsoft WebPages OAuth Library (see screenshot).
- This will install the library and a host of dependencies – fortunately none of these are membership dependencies. Once complete, if you look in your references folder you should find a number of OAuth references
Register with Facebook
I’d recommend following the steps under the section ‘Registering with an external provider’ shown here: http://www.asp.net/mvc/tutorials/security/using-oauth-providers-with-mvc to set up and configure your Facebook application.
Once complete you should have an App ID and a Secret key which we’ll need shortly.
Set up OAuth
Before your application starts it will be necessary to register the provider(s) you wish to offer. To accomplish this, create a new static class in the APP_START folder called OAuthProviders.cs and within a single static method called Configure. This is your first interaction with the OAuth libraries and where you will supply your credentials for Facebook:
1 2 3 4 5 6 7 8 9 10 11 12 |
using Microsoft.Web.WebPages.OAuth; namespace OAuthSample.App_Start { public static class OAuthProviders { public static void Configure() { OAuthWebSecurity.RegisterFacebookClient("YOUR APP ID", "YOUR APP SECRET"); } } } |
Be sure to add in your key (app id) and secret obtained in the previous step.
We then need to invoke this setup when the application starts, so in the Application_Start method inside your Global.asax, add in a call to the static configure class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using OAuthSample.App_Start; using System.Web.Mvc; using System.Web.Routing; namespace OAuthSample { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); OAuthProviders.Configure(); } } } |
Create the test page
Next, lets create a page that will let us invoke the OAuth process:
- Right-click on the controllers folder and click ‘add controller’
- Using VS2013, I’ll select the ‘MVC 5 Controller – Empty’ option to create a new controller and call it ‘HomeController’ for simplicity (by default, the MVC routing will look for this controller unless otherwise specified)
- MVC scaffolding will create an Index method for you – right click on this and click ‘add view’.
- In the resultant view, all we want to do is add a simple hyperlink back to the server that will let us invoke the OAuth Process:
1 2 3 4 5 6 7 |
@{ ViewBag.Title = "OAuth Sample"; } <h2>Demonstrating OAUth and Facebook in Asp.net</h2> @Html.ActionLink("Log in via facebook","facebook") |
All the above does is create a link back to a ‘facebook’ action on our Home Controller – let’’s create this method.
All we need is a single method call that tells Facebook where to post the result to once the client has completed authentication:
1 2 3 4 5 |
public void Facebook() { string returnURL = "~/home/oauthresult/"; OAuthWebSecurity.RequestAuthentication("facebook", returnURL); } |
In reality this would probably come from a config file or something but we’ll just hard code it for now.
As you can see, we’re telling facebook to invoke an action called ‘oauthresult’ once its completed, so lets create that action now:
1 2 3 |
public ActionResult OauthResult(){ return View(); } |
Now, the exciting part – lets run the app. Press F5 and you’ll see a gorgeous looking page with a log in link. Click it.
You will be taken to Facebook and asked to log in (if you aren’t already). Once logged in, Facebook should ask you to authorise the app you created earlier to access your email:
If you click OK, you should be sent back to your application but we’ll get an error as we haven’t created the view for that page yet. Lets do this now:
Amend your OAuthResult to parse some of the data returned from Facebook as follows:
1 2 3 4 5 6 7 8 9 10 11 |
public ActionResult OauthResult(){ var result = OAuthWebSecurity.VerifyAuthentication(); if (result.IsSuccessful) { @ViewBag.ProviderUserID = result.ProviderUserId; @ViewBag.Gender = result.ExtraData["gender"]; @ViewBag.Name = result.ExtraData["name"]; @ViewBag.AccessToken = result.ExtraData["accesstoken"]; } return View(); } |
Here you will see that we’re calling into the static method VerifyAuthentication() which will return an AuthenticationResult object. From here we can get access to all the token data Facebook provides, including name, email address, DOB, ID and more.
Add the view and set up the display of the data we loaded into the ViewBag (ideally, we’d create a strongly typed view model or pass the AuthenticationResult directly to the view, but this will be fine for demonstration purposes):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@{ ViewBag.Title = "OauthResult"; } <h2>OauthResult</h2> <table> <thead> <tr> <td>Key</td> <td>Value</td> </tr> <tr> <td>Facebook API ID</td> <td>@ViewBag.ProviderUserID</td> </tr> <tr> <td>Gender</td> <td>@ViewBag.Gender</td> </tr> <tr> <td>Name</td> <td>@ViewBag.Name</td> </tr> <tr> <td>Access token</td> <td>@ViewBag.AccessToken</td> </tr> </thead> </table> |
We’ve gone all out here and created a table which displays the basic information out of the viewbag. Go ahead and re-run the application – this time it should work end to end!
What next?
Now you’ve successfully authenticated the user via Facebook (in reality, thanks to the DotNetOpenAuth libraries this was only half a dozen lines of code!) they world is your oyster. The process is almost identical to integrate Google, Microsoft and LinkedIn, so go and try those (HINT: Where we set up the facebook provider credentials in the OAuthProviders class’ Configure() method, experiment with the RegisterTwitterClient(), RegisterMicrosoftClient() etc. etc.) . Also, now you’ve obtained your user access token from Facebook, you can start exploring the Facebook graph API and getting creative.
All this and not a database in sight.