Thursday, 6 November 2014

Integrate OpenAuth/OpenID with your existing ASP.NET MVC4 application


Step 1: Create a new project

Go to File –> New Project –> Web –> Empty Asp.Net MVC 4 Application

Step 2: Add the following libraries

  • Use Nuget to get the following packages
    • DotNetOpenAuth.AspNet
      • This package is the core package for OAuth/OpenID protocol communication
    • Microsoft.AspNet.Providers.Core
      • This package brings in Universal Providers
    • Microsoft.AspNet.Providers.LocalDb
      • This package sets the connectionstring for the Universal Providers
    • Microsoft.AspNet.Membership.OpenAuth
      • This package provides the extension to integrate OAuth/OpenID with Membership providers

Step 3: Change web.config to use formsauthentication



<authentication mode="Forms">
   <forms loginUrl="~/Auth/Logon" timeout="2880" />
</authentication>

Step 4: Adding AuthConfig

Add a new class called AuthConfig.cs to folder App_Start that class will contains the register functions for all services that we will integrate
Add the following code to AuthConfig.cs and don’t forget to get services Api keys from each service website


public static void RegisterAuth()
        {
            // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
            // you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166
            OAuthWebSecurity.RegisterMicrosoftClient(
                clientId: "",
                clientSecret: "");
            OAuthWebSecurity.RegisterTwitterClient(
                consumerKey: "",
                consumerSecret: "");
            OAuthWebSecurity.RegisterFacebookClient(
                appId: "",
                appSecret: "");
            OAuthWebSecurity.RegisterGoogleClient();
            OAuthWebSecurity.RegisterLinkedInClient(
                consumerKey: "",
                consumerSecret: "");
      OAuthWebSecurity.RegisterYahooClient();
}
Register AuthConfig to application start Go to Global.asax and add the following line to Application_Start function


AuthConfig.RegisterAuth();

Step 5: Adding Login functionality

Add a new controller for Authentication functionality called it AuthController.cs
add Logon Action for login page


public ActionResult Logon()
        {
            return View(OAuthWebSecurity.RegisteredClientData);
        }
as you can notice that we user OAuthWebSecurity.RegisteredClientData as a model that object will contain all registered services that we put at AuthConfig class. Add a markup for login page


@using Microsoft.Web.WebPages.OAuth;
@model ICollection<AuthenticationClientData>
//Add this inside body
<div>
        @using (Html.BeginForm("ExternalLogin", "Auth", new { ReturnUrl = ViewBag.ReturnUrl }))
        {
            @Html.AntiForgeryToken()
            <p>
                @foreach (AuthenticationClientData p in Model)
                {
                    <button type="submit" name="provider" value="@p.AuthenticationClient.ProviderName" title="Log in using your @p.DisplayName account">@p.DisplayName</button>
                }
            </p>
        }
    </div>
as you can notice that we are looping against the services that we already registered in a previous step each AuthenticationClientData represent a service so we create a button to call that service we are adding all the buttons inside single form that calling ExternalLogin action method
add ActionMethod ExternalLogin


[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public void ExternalLogin(string provider, string returnUrl)
{
  OAuthWebSecurity.RequestAuthentication(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
}
as you can notice its a void action. we are using OAuthWebSecurity.RequestAuthentication this function is requesting the authentication from the requested provider service “Facebook – Twitter – etc.” then it returned to The URL to return to when authentication is successful. we are mentioned “ExternalLoginCallback” as a returned back action


  [AllowAnonymous]
        public ActionResult ExternalLoginCallback(string returnUrl = "")
        {
            AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
            if (!result.IsSuccessful)
            {
                return RedirectToAction("ExternalLoginFailure");
            }
            //if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
            //{
            //    return RedirectToLocal(returnUrl);
            //}
            if (User.Identity.IsAuthenticated)
            {
                // If the current user is logged in add the new account
                OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                // User is new, ask for their desired membership name
                string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
                ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
                ViewBag.ReturnUrl = returnUrl;
                OAuthAccount oAuthAccount = new OAuthAccount(result.Provider, result.ProviderUserId);
                return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
            }
        }
 private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
First: we have to verify authentication to ensure that the account is successfully authenticated if not redirect users to ExternalLoginFailure action if user is authenticated then we are going to login user to the system using simple membership we are going to talk about that in later posts then check if the current user is logged in add the new account else user is new, ask for their desired membership name then redirect to ExternalLoginConfirmation action with user information at RegisterExternalLoginModel class


public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model)
       {
           return View(model);
       }
RegisterExternalLoginModel


public class RegisterExternalLoginModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }
        public string ExternalLoginData { get; set; }
    }
Finally: your application is ready to give it a test
You can download a sample from here

No comments:

Post a Comment

Angular Tutorial (Update to Angular 7)

As Angular 7 has just been released a few days ago. This tutorial is updated to show you how to create an Angular 7 project and the new fe...