Using MVC4 and OAuth to log in with a Facebook, Google, LinkedIn, Microsoft, Twitter, Yahoo! or StackExchange account

Tags: MVC4, DotNetOpenAuth, OAuth, Custom OpenIdClient, Facebook, Google, LinkedIn, Microsoft, Twitter, StackExchange, Yahoo

Using MVC4 and OAuth to log in with a Facebook, Google, LinkedIn, Microsoft, Twitter, Yahoo! or StackExchange account

Overview

With the release of Visual Studio 2012 Microsoft has added OAuth support to the .NET framework making it incredibly easy for users to authenticate using their existing accounts on other popular web sites including Facebook, Google, LinkedIn, Microsoft, Twitter, and Yahoo!.  And you can easily add more using a custom provider like we do in this article for StackExchange.  The DotNetOpenAuth open source project has been incorporated into the project templates to accomplish this for all types of .NET project types.  This article will describe how to enable all of these logins in MVC 4 and the source code for this project is available for download at the end of this article.

Obtain the IDs and Secret Keys to login with OAuth

In order to enable logins for Facebook, LinkedIn, Microsoft and Twitter the first thing you will need to do is to register at these sites and get an ID and a secret key.  Since the site ID and secret keys are not included in the sample source code, you must obtain that information for all of the logins you would like to support.  Google, Yahoo and StackExchange do not require that your application provides an ID and a Secret Key for a user to authenticate, but you may still want to register your application with them if you are enabling those services.

The discussion below assumes you just created an MVC 4 web application using the Internet template.  Once you implement support for all of the providers the login page will show the buttons for the providers a user can login with:

OAuth Login Providers

Facebook

In order to support Facebook you must

·        Navigate to Facebook and login

·        Go to the Facebook Developers page at https://developers.facebook.com/apps

·        Push the “Create New App” button

·        For purposes of our sample application we will integrate with Facebook using the Website with Facebook Login, so push on the Checkmark to enable this option

·        If you are using IIS Express to run and debug your application in Visual Studio fill in the Site URL: with http://localhost:{Port #} where {Port #} is replaced by the port number.  If the port changes you will need to update your App Page on Facebook or the callback will fail.  But if you used IIS Server Manager to create an application that is used for running the project, or you are pointing to a live web site, then use the URL for your application instead.

 

·        Push the “Save Changes” button

·        Open the App_Start\AuthConfig.cs file in the OAuthWithMvc4 web project file, uncomment the 3 lines that make the call to OAuthWebSecurity.RegisterFacebookClient, and paste the values for App ID and App Secret into the respective variables that are passed to RegisterFacebookClient

·        If an image is desired in the button you must also add the display name as Facebook and the image file to use as extra data as shown below where the x’s are replaced with your appId and appSecret

o         // Facebook

o         Dictionary<string, object> facebookExtraData = new Dictionary<string, object>();

o         facebookExtraData.Add("Icon", "../Images/facebook.png");

o         OAuthWebSecurity.RegisterFacebookClient(

o             appId: "xxxxxxxxxxxxxxx",

o             appSecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

o             displayName: "Facebook",

o             extraData: facebookExtraData); 

·         To make sure that everything is configured correctly, run the application, Push the Login link and you should a page similar to the following (except with your application and login credentials on it):

·        Push the “Go to App” button

·        Push the Register button in the following page to complete the process:

Facebook Register OAuth 

The next time you try and Login using your Facebook account you will just need to push on the Facebook button: how cool is that?  But wait, there’s more!

Google

Google does not require an ID and Secret Key in order to login, but if desired you can register your application with the Google APIs console at https://code.google.com/apis/console#access and receive a Client ID and Client Secret key.

 To make sure you can login with Google

 ·        If you are still logged in with Facebook push the Logout link

 ·        Push the Login link

 ·        Push the Google Button

·        When prompted (as shown below) push Allow (leaving Remember this approval checked)

·     

·        Push the Register button to complete the registration process

Google Register OAuth 

The next time you try and Login using your Google account you will just need to push the Google button: very easy but very cool!

LinkedIn

Register your application on LinkedIn to receive an API key at https://www.linkedin.com/secure/developer (logging into your LinkedIn account when asked if you are not already)

·        Push the “Add new Application” link and enter the required information leaving the OAuth Redirect URL blank

·        Copy the API Key and the Secret Key into the App_Start\AuthConfig.cs file in the consumerKey and consumerSecret properties for the RegisterLinkedInClient method call

Noe that while initially testing with LinkedIn I was unable to authenticate until I came across a blog that mentioned this is a known bug and provided a Custom Client implementation that did work properly (thanks Mr. Roa!).

·        To make sure that everything is configured correctly, run the application, push the Login link, push the LinkedIn button  and you should a page similar to the following (except with your application and login credentials on it):

LinkedIn Access OAuth

 ·        Push the "Allow access" button

LinkedIn Register OAuth

 ·        Push the Register button to copmlete the process

Microsoft Account

First you must register your application

 ·       Navigate to the developers site for Windows Live at http://msdn.microsoft.com/library/live/

 ·        Select the "My Apps" link

 ·        Select the "Create application" link

 ·        Enter the required information

Note: for local testing we are going to use localtest.me, a public test domain that will redirect back to 127.0.0.1 or localhost since Microsoft will not redirect to localhost on it's own.  For more information, see http://readme.localtest.me/ but the bottom line is enter something like http://oauthwithmvc4.localtest.me/ (where oauthwithmvc4 is the name of your application) as the redirect domain. 

Add the Client ID and Client Secret provided in the \App_Start\AuthConfig.cs file

You will also need to do the following on your local machine:

1) open up port 80 in your firewall at least temporarily until you are done with your tests, and then you should disable the rule when you are done.  Information on how to do this in Windows 7 and Windows 8 can be found at

http://maximumpcguides.com/windows-7/open-a-port-in-windows-7s-firewall/

If you are using IIS Express edit your applicationHost.config file in your %Documents%\IISExpress\Config folder

adding a binding for port 80 and the domain name to this web application under the <bindings>, e.g.

<binding protocol="http" bindingInformation="*:80:OAuthWithMVC4.localtest.me " />

and then restart IIS Express and rerun the application 

If you created a virtual directory in IIS, use IIS Server Manager to add a site binding which maps port 80 to your test application, e.g.

IIS Site Binding

 In order for this to run you must go into the web project's properties page, select web, and indicate Use Custom Web Server.

test the application by running it in visual studio

·        Select the “Applications settings page”

Microsoft Access OAuth 

Once you are logged in you will be asked to register with your application as before:

Microsoft Register OAuth

Twitter

  • Navigate to the Twitter developers site at https://dev.twitter.com,
  • Push the “Create an App” link and log in with your Twitter account
  • On the Create an Application form, enter a Name and Description for your application
  • In the Website field enter the URL of your public web site - for example, http://www.mvcrocksonasp.net.
  • Enter the Callback URL.  While you are still developing and testing your application you cannot use localhost like we did for other services, so use the built-in tcp/ip address for localhost b entering http://127.0.0.1:{Port #} 

Twitter Authorize OAuth

·        After acknowledging that you accept the terms, you can push the “Create your Twitter application” button

·        Push the link to navigate back to the application you created, and use the “Create My Access Token” button on the Details tab to create the values needed for OAuth

·        Copy the Consumer Key and Consumer Secret value  into the consumerKey and consumerSecret parameters for the RegisterTwitterClient in the App_Start\AuthConfig.cs file in the OAuthWithMvc4 web project file, uncomment the 3 lines that make the call to OAuthWebSecurity.RegisterFacebookClient, and paste the values for App ID and App Secret into the respective variables that are passed to RegisterFacebookClient

·        To make sure that everything is configured correctly, run the application, Push the Login link and you should a page similar to the following (except with your application and login credentials on it):

 Twitter Register OAuth

Yahoo

Yahoo does not require an ID and Secret Key in order to login, but if desired you can register your application as a developer with Yahoo at https://developer.apps.yahoo.com/wsregapp/index.php

 To make sure you can login with Yahoo

 ·        If you are still logged in with OAuth provider push the Logout link

·        Push the Login link

·        Push the Yahoo button

·        When prompted (as shown below) push Allow leaving Remember this approval checked

 Yahoo Login OAuth

·        Push the Register button to complete the registration process

Unlike some of the other services, with Yahoo account I still had to Agree to using my Yahoo ID! (at least when testing on my local machine) every time I logged in using my Yahoo! Account.

Implementing a Custom Client with StackExchange

In addition to the built-in list of providers, you can create a client for any custom Open ID providers you wish to support (including your own).  We will create a client for the StackExchange OpenID (used by Stackoverflow and a number of other web sites).

You can add support for specific OpenID providers like StackExchange by creating a class that implements dotNetOpenAuth.Aspnet.IAuthenticationClient.  The implementation for the StackExchange Client is as follows:

 

  /// <summary>

  /// Represents a StackExchange OpenID client.

  /// </summary>

  public class StackExchangeClient : OpenIdClient

  {

    public StackExchangeClient() : base("stackexchange", "https://openid.stackexchange.com") { }


    protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response)

    {

      FetchResponse fetchResponse = response.GetExtension<FetchResponse>();


      if (fetchResponse != null)

      {

        var extraData = new Dictionary<string, string>();

        extraData.Add("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email));

        extraData.Add("fullname", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.FullName));

        return extraData;

      }


      return null;

    }


    protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request)

    {

      var fetchRequest = new FetchRequest();

      fetchRequest.Attributes.AddRequired(WellKnownAttributes.Contact.Email);

      fetchRequest.Attributes.AddRequired(WellKnownAttributes.Name.FullName);

      request.AddExtension(fetchRequest);

    }

  }

And registering the StackExchange client works the same as the other clients:

       // Register StackExchange Client

      Dictionary<string, object> stackExchangeExtraData = new Dictionary<string, object>();

      stackExchangeExtraData.Add("Icon", "../Images/StackExchange.png");

      OAuthWebSecurity.RegisterClient(

        client: new App_Start.StackExchangeCustomClient(),

        displayName: "StackExchange",

        extraData: stackExchangeExtraData);

And then when you run the application you will be presented with the following message from StackExchange

Once you login you will be asked if your account information can be accessed

StackExchange Login OAuth

And confirming brings you to a page to register in your application like

 StackExchange Register OAuth

Errors associating a user account

After changing the application name and trying to verify that I could still log in with the accounts I setup I ran into a problem logging into Google because my user name was already registered.

 Duplicate User Name

Although changing the User name resolved the problem and I was able to log in I was curious they the registration failed so I did a little research. 

After connecting to the external OAuth account, an attempt was made to add the user account to the applications local Membership Provider database (in this case aspnet-OAuthWithMvc4-{datetime}.mdb file in the web site’s App_Data folder.    

When a user registers with an application for the first time a record is added to the UserProfile table in the aspnet membership provider database.  A record was also created in the webpages_OAuthMembership table that associates this user record with the external provider

 OAuth Membership Duplicate

When I ran into the problem logging in because my user name already existed with the same ID, so I had to delete the offending row from this table to use the same user name again.

Source Code for existing providers

The DotNetOpenAuth library that Microsoft has bundled in with Visual Studio 2012 is open source.  If you want to look up how something was implemented in DotNotOpenAuth the source code for existing providers is public and can be accessed at https://github.com/AArnott/dotnetopenid/tree/master/src/DotNetOpenAuth.AspNet/Clients

Source Code for the sample application

OAuthWithMVC4.zip

References

http://www.asp.net/vnext/overview/videos/oauth-in-the-default-aspnet-45-templates Provides a video introduction to this topic

http://blogs.msdn.com/b/webdev/archive/2012/08/15/oauth-openid-support-for-webforms-mvc-and-webpages.aspx shows how to implement Facebook, Twitter, Google, and Yahoo! and has some links at the end to some additional reasources

http://blog.mrroa.com/post/30454808112/asp-net-custom-linkedin-oauth-provider documented the DotNetOpenAuth bug preventing the default LinkedIn implementation to authenticate, and provided a custom Linked In client that works until the core issue is fixed.

20 Comments

  • Peter Williams said

    I went a bit further.

    1. made my own IauthenticationClients - so the framework talks more than OUATH or openid protocols. Mine talk ws-fedp and some proprietary stuff.

    2. changed the scripting so that one particular registered client controls the localid.

  • MarkusR said

    The only problem I see is that, at least for yahoo and google, is that if the user is already logged in to Yahoo, for example, they are not give a chance to use a different account in this implementation. The yahoo login screen does not have this feature. I believe that other implementation of oauth use a yahoo login screen that lets you choose a different account.

  • Clifton Wesby said

    Additional note to users of this tutorial,for which I am very thankful for, you must register as a developer before the "Create a new app" button appears.

  • strona said

    Thank you a lot on behalf of sharing this with all those you really understand what you're talking about! Bookmarked. Delight and holiday at my website =). We could have a link swap harmony among us!

  • Nigel Stapels said

    Your style is unique compared to other people I have read stuff from.
    Thank you for posting when you have the opportunity, Guess I will just bookmark this web site.

  • Anastasia Latimer said

    Someone essentially help to make significantly articles I might state. That is the first time I frequented your website page and so far?
    I surprised with the research you made to create this actual post extraordinary. Excellent job!

  • Lazaro Baxter said

    Wonderful blog you have here but I was wanting to know if you knew of any forums that cover the same topics talked about in this article? I'd really love to be a part of online community where I can get responses from other experienced individuals that share the same interest. If you have any suggestions, please let me know. Thank you!

  • Jacques Reynolds said

    Hi would you mind sharing which blog platform you're using? I'm going to start my own blog soon but I'm having a hard time deciding between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your layout seems different then most blogs and I'm looking for something unique.
    P.S Sorry for getting off-topic but I had to ask!

  • Matilda Hickey said

    Very good info. Lucky me I found your website by accident (stumbleupon).

    I've bookmarked it for later!

  • Rosalyn Luke said

    Hello outstanding blog! Does running a blog like this take a great deal of work? I've virtually no expertise in coding but I had been hoping to start my own blog in the near future. Anyway, should you have any ideas or tips for new blog owners please share. I understand this is off topic however I simply had to ask. Many thanks!

  • Freeman Burns said

    Nice blog here! Also your website loads up very fast!

    What host are you using? Can I get your affiliate link to your host?

    I wish my site loaded up as fast as yours lol

  • Julius Newell said

    Excellent site. Lots of useful info here. I'm sending it to a few buddies and also sharing in delicious. And certainly, thanks for your effort!

  • Johnny Grantham said

    Everything is very open with a clear clarification of the challenges.

    It was definitely informative. Your website is very helpful.

    Thanks for sharing!

  • Zelda Dickens said

    Wow, amazing blog layout! How long have you been blogging for?

    You made blogging look easy. The overall look of your website is magnificent, let alone the content!

  • Bessie Gainey said

    After looking over a few of the blog posts on your site, I honestly like your way of blogging. I book-marked it to my bookmark website list and will be checking back in the near future.

  • Tegan Thames said

    You really make it seem so easy with your presentation but I find this matter to be really something which I think I would never understand. It seems too complicated and extremely broad for me.

    I am looking forward for your next post, I'll try to get the hang of it!

  • humbertom claurin said

    Amazing blog! Is your theme custom made or did you download it from somewhere?
    A design like yours with a few simple adjustements would really make
    my blog stand out. Please let me know where you got your design.
    Kudos

  • Luke Haley said

    It's really a nice and helpful piece of information. I'm glad that you simply shared this useful info with us. Please keep us informed like this.
    Thank you for sharing.

  • Bridget Cline said

    I have been browsing online more than 3 hours today, yet I never found any interesting article like
    yours. It's pretty worth enough for me. In my view, if all webmasters and bloggers made good content as you did, the net will be much more useful than ever before.

Comments have been disabled for this content.