Implement Facebook Login with OpenID Selector in MVC3





5.00/5 (3 votes)
How to use the OpenId selector tool in an ASP.NET MVC3 application
In my last post, I explained how we can implement Facebook login with OpenId
selector tool. In this post, I will explain how we can use that tool in an ASP.NET MVC3 application.
- Open Visual Studio 2010 go to File > New > Project > Web > ASP.NET MVC 3 application:
Then choose Internet Application. Be sure to have Razor as your View engine and click OK:
- Download DotNetOpenAuth DLL and Updated OpenID Selector files that we will use.
- Add the DotNetOpenAuth.dll to references in your site.
- Copy all contents of openid-selector\css folder to the 'Content' folder.
- Copy images, images.large, images.small folders to the site 'Content' folder.
- Copy openid-jquery.js, openid-en.js files from openid-selector\js folder to 'Scripts' folder.
Your Solution Explorer will look like this (see the highlighted portion):
- Go to Views > Shared > _Layout.cshtml and replace the
<head>
with this new head with new styles and scripts:<head> <meta charset="utf-8" /> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script> <link href="@Url.Content("~/Content/openid-shadow.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/openid.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/openid-jquery.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/openid-en.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> <script type="text/javascript" src="https://connect.facebook.net/en_US/all.js"> </script> <script type="text/javascript"> $(document).ready(function () { openid.init('openid_identifier'); }); </script> </head>
- Go to Models > AccountModels.cs, navigate to
public class LogOnModel
and AddOpenID
attribute that we will use to hold the returnedOpenID
fromOpenID
-Selector.Your class will look like this:
public class LogOnModel { [Display(Name = "OpenID")] public string OpenID { get; set; } [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } }
- Go to Models > AccountModels.cs and add the following class to it:
public class UserDetailsModel { public string OpenID { get; set; } public string ProviderUrl { get; set; } public string FriendlyIdentifier { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Dob { get; set; } public string Gender { get; set; } public string Email { get; set; } }
- Go to Views > Account > LogOn.cshtml. Replace all the markup with this one. This will integrate updated
OpenID
-Selector to LogOn View:@model FBOpenIDMVC3.Models.LogOnModel @{ ViewBag.Title = "Log On"; } <h2> Log On</h2> <p> Please enter your username and password. @Html.ActionLink("Register", "Register") if you don't have an account. </p> <script type="text/javascript"> $(document).ready(function () { // Init the SDK upon load window.fbAsyncInit = function () { FB.init({ appId: '188220747944294', // App ID channelUrl: '//' + window.location.hostname + '/channel', // Path to your Channel File scope: 'id,name,first_name,last_name,gender,email', status: true, // check login status cookie: true, // enable cookies to allow the server to access the session xfbml: true // parse XFBML }); }; }); /*This Method will be invoked on lick on Facebook button*/ function FBLogin() { FB.login(FBCallBack); } function FBCallBack(response) { if (response.authResponse) { // user has auth'd your app and is logged into Facebook FB.api('/me?fields=id,name,first_name, last_name,gender,email,birthday', function (userDetail) { if (userDetail.name) { var url = '@Url.Action("ShowUserDetails", "Account", new { OpenID = "_id_", FriendlyIdentifier = "_id_", FirstName = "_first_", LastName = "_last_", Dob = "_birthday_", Gender = "_gender_", Email = "_email_" })'; url = url.replace('_id_', userDetail.id); url = url.replace('_id_', userDetail.id); url = url.replace('_first_', userDetail.first_name); url = url.replace('_last_', userDetail.last_name); url = url.replace('_birthday_', userDetail.birthday); url = url.replace('_gender_', userDetail.gender); url = url.replace('_email_', userDetail.email); window.location.href = url; } }); } } </script> <form action="Authenticate?ReturnUrl=@HttpUtility.UrlEncode (Request.QueryString["ReturnUrl"])" method="post" id="openid_form"> <input type="hidden" name="action" value="verify" /> <div> <fieldset> <legend>Login using OpenID</legend> <div class="openid_choice"> <p> Please click your account provider:</p> <div id="openid_btns"> </div> </div> <div id="openid_input_area"> @Html.TextBox("openid_identifier") <input type="submit" value="Log On" /> </div> <noscript> <p> OpenID is service that allows you to log-on to many different websites using a single indentity. Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p> </noscript> <div> @if (Model != null) { if (String.IsNullOrEmpty(Model.UserName)) { <div class="editor-label"> @Html.LabelFor(model => model.OpenID) </div> <div class="editor-field"> @Html.DisplayFor(model => model.OpenID) </div> <p class="button"> @Html.ActionLink("New User ,Register", "Register", new { OpenID = Model.OpenID }) </p> } else { //user exist <p class="buttonGreen"> <a href="@Url.Action("Index", "Home")">Welcome , @Model.UserName, Continue..." </a> </p> } } </div> </fieldset> </div> </form> @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") @using (Html.BeginForm()) { <div> <fieldset> <legend>Or Login Normally</legend> <div class="editor-label"> @Html.LabelFor(m => m.UserName) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.UserName) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="editor-label"> @Html.LabelFor(m => m.Password) </div> <div class="editor-field"> @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <div class="editor-label"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> <p > <input type="submit" value="Log On" /> </p> </fieldset> </div> }
- Update the value of
img_path
in openid-jquery.js to '../Content/images/'. - Now let us run the project, then click the [Log On] link, you will get something like this page:
- Now to implement Open ID using
DotnetOpenAuth
, Go to Controllers > AccountController.cs and add theseusing
s:using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
Then, add the following code to AccountController.cs:
private static OpenIdRelyingParty openid = new OpenIdRelyingParty(); [ValidateInput(false)] public ActionResult Authenticate(string returnUrl) { var response = openid.GetResponse(); if (response == null) { //Let us submit the request to OpenID provider Identifier id; if (Identifier.TryParse(Request.Form["openid_identifier"], out id)) { try { var request = openid.CreateRequest (Request.Form["openid_identifier"]); var fetch = new FetchRequest(); fetch.Attributes.Add(new AttributeRequest (WellKnownAttributes.Contact.Email, true)); fetch.Attributes.Add(new AttributeRequest (WellKnownAttributes.BirthDate.WholeBirthDate, true)); fetch.Attributes.Add(new AttributeRequest (WellKnownAttributes.Person.Gender, true)); fetch.Attributes.Add(new AttributeRequest (WellKnownAttributes.Name.First, true)); fetch.Attributes.Add(new AttributeRequest (WellKnownAttributes.Name.Last, true)); request.AddExtension(fetch); return request.RedirectingResponse.AsActionResult(); } catch (ProtocolException ex) { ViewBag.Message = ex.Message; return View("LogOn"); } } ViewBag.Message = "Invalid identifier"; return View("LogOn"); } //Let us check the response switch (response.Status) { case AuthenticationStatus.Authenticated: var fetch = response.GetExtension<FetchResponse>(); var sFirstName = ""; var sEmail = ""; var sLastName = ""; var sGender = ""; var sDob = ""; if (fetch != null) { foreach (var vAtrrib in fetch.Attributes) { switch (vAtrrib.TypeUri) { case WellKnownAttributes.Name.First: var firstNames = fetch.Attributes [WellKnownAttributes.Name.First].Values; sFirstName = firstNames.Count > 0 ? firstNames[0] : null; break; case WellKnownAttributes.Contact.Email: var emailAddresses = fetch.Attributes [WellKnownAttributes.Contact.Email].Values; sEmail = emailAddresses.Count > 0 ? emailAddresses[0] : null; break; case WellKnownAttributes.Name.Last: var lastNames = fetch.Attributes [WellKnownAttributes.Name.Last].Values; sLastName = lastNames.Count > 0 ? lastNames[0] : null; break; case WellKnownAttributes.Person.Gender: var genders = fetch.Attributes [WellKnownAttributes.Person.Gender].Values; sGender = genders.Count > 0 ? genders[0] : null; break; case WellKnownAttributes.BirthDate.WholeBirthDate: var doBs = fetch.Attributes [WellKnownAttributes.BirthDate.WholeBirthDate].Values; sDob = doBs.Count > 0 ? doBs[0] : null; break; } } } var sFriendlyLogin = response.FriendlyIdentifierForDisplay; var lm = new UserDetailsModel { OpenID = response.ClaimedIdentifier, FriendlyIdentifier = sFriendlyLogin, FirstName = sFirstName, LastName = sLastName, Dob = sDob, Gender = sGender, Email = sEmail }; FormsService.SignIn(sEmail, false); return View("ShowUserDetails", lm); case AuthenticationStatus.Canceled: ViewBag.Message = "Canceled at provider"; return View("LogOn"); case AuthenticationStatus.Failed: ViewBag.Message = response.Exception.Message; return View("LogOn"); } return new EmptyResult(); } public ActionResult ShowUserDetails(UserDetailsModel objUserDetails) { return View(objUserDetails); } [HttpPost] public ActionResult ShowUserDetails(string OpenID, string FriendlyIdentifier, string FirstName, string LastName, string Dob, string Gender, string Email) { var objUserDetails = new UserDetailsModel() { OpenID = OpenID, FriendlyIdentifier = FriendlyIdentifier, FirstName = FirstName, LastName = LastName, Dob = Dob, Gender = Gender, Email = Email, }; return View(objUserDetails); }
- Right click on Views--> Accounts and click Add-->View to add new view like this:
- Add the following code in this View:
public class UserDetailsModel { public string OpenID { get; set; } public string ProviderUrl { get; set; } public string FriendlyIdentifier { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Dob { get; set; } public string Gender { get; set; } public string Email { get; set; } }
- Now run the project click [Log On] link and click a provider like Google. It may ask you to sign in or ask you to allow access to your information. You will get a page like this:
Congratulations! Now you have integrated OpenID
login with Facebook login to your project.