This post discusses how open id registration is being intergated with the Geostore project. The implementation is general and could be used in any ASP.net project.
Create Project
- Choose ASP.Net MVC3 web application.
![]() |
MVC3 application wizard step-1 |
- On project template choose Internet Application
- On this page select Razor option in View Engine selection box.
- Select check box Use HTML5 semantic markup.
Add following references to the project:
- DotNetOpenAuth: (DotNetOpenAuth.dll)
- JSON.NET: (Newtonsoft.Json.dll)
This library is used to implement OpenId and OAuth implementation in ASP.net. It is widely used and is actively being supported by the developer.
This library is used to read and produce json files and strings.
RegisterOpenIdModel
We need a model object to pass data between controller and view which implements OpenId registration. We define a model to store OpenId information in AccountModel.cs. AccountModel.cs file is generated by the ASP.net wizard and is available in the Models folder of the project. Open AccountModels.cs file and define RegisterOpenIdModel.
AccountController.cs
public class RegisterOpenIdModel { [Required] [StringLength(5)] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.EmailAddress)] [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Please enter a valid email address.")] [Display(Name = "Email address")] public string Email { get; set; } [Required(ErrorMessage = "Please select openID identifier."] [DataType(DataType.Text)] [Display(Name = "OpenId")] public string openid_identifier { get; set; } }This model contains three fields: user name, email address and open_identifier. We have also added basic validation logic with the model. This way of handling validation is often referred as DRY ("Dont Repeat Yourself"). Please refer here for more details about DRY implementation.
AccountController.cs
This controller is generated by the ASP.Net MVC3 web application wizard and it contains implementation of membership module. We will extend this module to implement OpenId implementation. First we add references to DotNetOpenAuth and NewtonSoft libraries in this controller.
Now we add a method in this controller to display a view which allows users to register with the system using open id.
using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Messaging; using Newtonsoft.Json;
// // GET: /Account/RegisterOpenId [HttpGet] public ActionResult RegisterOpenId() { return View(); }
RegisterOpenId View
RegisterOpenId view allows users to register with the system using their open id. It is shown in the following figure:
![]() |
RegisterOpenId view: This view uses OpenID to register users with the system. |
As shown in above figure, this view asks for user name, email and open id provider. When user clicks register button, the form is redirected to selected open id provider login screen. The user then enters login information on open id provider login screen to verify her open id credentials.
In order to create RegisterOpenId view we use new view wizard. This view is based on Razor framework and uses RegisterOpenId model. The values are provided as shown in the following figure:
As shown in above figure we have given the name of view as RegisterOpenId. we have selected view engine as Razor and selected the option to create a strongly-typed view based on RegisterOpenIdModel. We have selected Create option for scaffold template.
If we run this application now by typing localhost:port/Account/RegisterOpenId we get view which provides basic create functionality as shown in following figure:
![]() |
RegisterOpenId with create functionality |
Create a new class user using class wizard. This wizard generates following code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GeoStoreAuthApplication.Models { interface user { } }Replace interface code with the following implementation and resolves any missing package errors using resolve menu option.
public partial class user : EntityObject { public static user getUserByName(string userName) { GeoStoreDBEntities db = new GeoStoreDBEntities(); var userQuery = from userObj in db.users where userObj.name == userName select userObj; var users = userQuery.ToList(); if (users.Count > 0) return users.Single(); else return null; } public static user getUserByEmail(string email) { GeoStoreDBEntities db = new GeoStoreDBEntities(); var userQuery = from userObj in db.users where userObj.email == email select userObj; var users = userQuery.ToList(); if (users.Count > 0) return users.Single(); else return null; } public static user getUserByOpenID(string openid) { GeoStoreDBEntities db = new GeoStoreDBEntities(); var userQuery = from userObj in db.users where userObj.open_id == openid select userObj; var users = userQuery.ToList(); if (users.Count > 0) return users.Single(); else return null; } public static user createUser(user userObj){ GeoStoreDBEntities db = new GeoStoreDBEntities(); db.users.AddObject(userObj); db.SaveChanges(); return (getUserByName(userObj.name)); } }In functions: getUserByName, getUserByEmail and getUserByOpenID we retrieve existing user object from the database using input parameter. The last function createUser is used to save user data into the database. Now we define two get functions in AccountController.cs. These functions are called from RegisterOpenId view as AJAX calls to check if there is already a user with input user name and email exists into the database.
//This class is used to send verification messages. class VerificationResponse { public int status; public string message; } //Get: /Account/VerifyUser //This function is used to check if user with input name exists in the database. [HttpGet] public string VerifyUser(string userName) { VerificationResponse verificationResponse = new VerificationResponse(); GeoStoreDBEntities db = new GeoStoreDBEntities(); user userObj = user.getUserByName(userName); if (userObj != null) { verificationResponse.status = 0; verificationResponse.message = "This user name is not available. Please choose another name."; } else { verificationResponse.status = 1; verificationResponse.message = "This User name is available."; } return JsonConvert.SerializeObject(verificationResponse); } //Get: /Account/VerifyEmailAddress //This function is used to check if user with email address exists in the database. [HttpGet] public string VerifyEmailAddress(string email) { VerificationResponse verificationResponse = new VerificationResponse(); GeoStoreDBEntities db = new GeoStoreDBEntities(); var userObj = user.getUserByEmail(email); if (userObj != null) { verificationResponse.status = 0; verificationResponse.message = "This email is already registered. You might have already registered with us."; } else { verificationResponse.status = 1; verificationResponse.message = ""; } return JsonConvert.SerializeObject(verificationResponse); }Both of the above functions are defined as HttpGet which means these functions could be called from a view to perform their respective tasks. The first function verifyUser receives userName as an input and it calls user.getUserByName to get user object which matches specified user name. If a record does not exist in the database then a response message with status 0 is sent. Otherwise a response message with status 1 is returned. Similarly logic is implemented in VerifyEmailAddress function.
Everything is now in place to make AJAX calls from RegisterOpenId view. We update RegisterOpenId.cshtml (view) to refer to following files:
- jquery.min.js: This file is jQuery java script file.
- jquery.openid.js: This file comes with the open id jquery plugin which we have used on our form. We have modified this file according to our needs.
- openid.css: This file also comes with the open id jquery plugin. We have also modified this files based on our implementation.
<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="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script> <script type="text/javascript" src="@Url.Content("~/scripts/jquery.openid.js")"></script> <link href="@Url.Content("~/Content/openid.css")" rel="stylesheet" type="text/css" /> <script type="text/javascript"> $(function () { $("form.RegisterOpenid").openid(); }); </script>In above code we have added paths for jquery scripts and open id plugins. We have also added style sheet of open id plugin. We will discuss about open id plugin later in this article. We also add two span html mark-ups in the RegisterOpenId view to display validation messages. These html mark-ups are defined as:
<span id="UserNameValidation" class="UserNameValidation"></span> <span id="EmailAddressValidation" class="EmailAddressValidation"></span>These span elements are used to show validation messages. We also define the action, request type and class of RegisterOpenId.cshtml form. When this form is posted it invokes AuthenticateOpenId action which is defined in Account controller class. The html code for the form including span mark-ups is shown below.
@using (Html.BeginForm("AuthenticateOpenIdUser", "Account", FormMethod.Post, new{@class = "RegisterOpenid"})){ @Html.ValidationSummary(true) <fieldset> <legend>RegisterOpenIdModel</legend> <div class="editor-label"> @Html.LabelFor(model => model.UserName) </div> <div class="editor-field"> @Html.EditorFor(model => model.UserName) @Html.ValidationMessageFor(model => model.UserName) <span id="UserNameValidation" class="UserNameValidation"></span> </div> <div class="editor-label"> @Html.LabelFor(model => model.Email) </div> <div class="editor-field"> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) <span id="EmailAddressValidation" class="EmailAddressValidation"></span> </div> <div class="editor-label"> @Html.LabelFor(model => model.openid_identifier) </div> <div class="editor-field"> @Html.EditorFor(model => model.openid_identifier) @Html.ValidationMessageFor(model => model.openid_identifier) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div>If you remember one of the reason to define validation messages and span mark-ups is to call validation functions,VerifyUser and VerifyEmailAddress, when user enters user name and email address. To improve user experience these calls would be made through AJAX. To implement this we define javascripts functions in jquery.openid.js. Remember that the jquery.openid.js comes with open id plugin and we modify this plugin according to our needs.
//Validation Methods var updateUserNameValidationMessage = function (event) { var value = $.trim(event.target.value) if (value.length > 0) { $.getJSON('/Account/VerifyUser', $.param({ 'userName': event.target.value }), function (response) { $('#UserNameValidation').data('status', response.status); $('#UserNameValidation').html(response.message); if ($('#UserNameValidation').is(':hidden')) $('#UserNameValidation').css("display", 'inline'); }); } else { $('#UserNameValidation').hide(); } }; var updateEmailValidationMessage = function (event) { var value = $.trim(event.target.value) if (value.length > 0) { $.getJSON('/Account/VerifyEmailAddress', $.param({ 'email': event.target.value }), function (response) { $('#EmailAddressValidation').data('status', response.status); $('#EmailAddressValidation').html(response.message); if ($('#EmailAddressValidation').is(':hidden')) $('#EmailAddressValidation').css("display", 'inline'); }); } else { $('#EmailAddressValidation').hide(); } };updateUserNameValidationMessage receives event object as an input. This event object is a jQuery object and it contains information about the event and value entered by the user. We retrieve the value from the event.target object and check its length. If length is greater than 0 i.e a value is given then we make an AJAX call to the function VerifyUser. If you remember we define VerifyUser in AccountController.cs file. This function receives user name and returns verification response object. Verification response object contains message and status value. If VerifyUser function finds a user object in the database which contains same user name then it notifies the user that the name already exists. Otherwise it notifies that the entered user name is available. Verification response object contains status and message. We store status value in the custom html attribute called status which is associated with the UserNameValidation html mark-up. We add message string obtained from the verification response object into the html of UserNameValidation mark-up. We also make the control visible if it is hidden. If length of event.target.value is empty then we hide validation message. Because in this case there is no need to display validation message to the user. updateEmailValidationMessage performs similar function for input email address. We call updateUserNameValidationMessage and updateEmailValidationMessage functions when user enters or change user name or email address. In order to associate these functions with data entry and change events we define following code:
$('#UserName').keyup(updateUserNameValidationMessage); $('#UserName').change(updateUserNameValidationMessage); $('#Email').keyup(updateEmailValidationMessage); $('#Email').change(updateEmailValidationMessage);If we now run our application we get output as shown in following figure:
![]() |
RegisterOpenId.cshtml with UserName and Email validations. |
Open id plugin
Open id plugin provides a list of open id providers which user can select to authenticate with the open id provider. Please note that the Open id plugin only provides an interface to select a particular open id provider. The underlying mechanism of authentication is done by DotNetOpenAuth library. We will discuss about DotNetOpenAuth later. The user interface of OpenId plugin can be seen here. In order to integrate this plugin with our interface we delete html mark-ups corresponding to open_identifier from the RegisterOpenId.cshtml.
<div class="editor-label"> @Html.LabelFor(model => model.openid_identifier) </div> <div class="editor-field"> @Html.EditorFor(model => model.openid_identifier) @Html.ValidationMessageFor(model => model.openid_identifier) </div>We replace this with open id provider list.
<span class="caption">Please select your open id.</span> @Html.ValidationMessageFor(m => m.openid_identifier) <div class = "openid"> <ul class="providers"> <li class="direct" title="Google" data-custom-title="Google"> <img src="@Url.Content("~/images/googleW.png")" alt="icon" /><span>https://www.google.com/accounts/o8/id</span></li> <li class="direct" title="Yahoo" data-custom-title="Yahoo"> <img src="@Url.Content("~/images/yahooW.png")" alt="icon" /><span>http://yahoo.com/</span></li> <li class="openid" title="OpenID" data-custom-title="OpenID"><img src="@Url.Content("~/images/openidW.png")" alt="icon" /> <span><strong>http://{your-openid-url}</strong></span></li> <li class="username" title="AOL screen name" data-custom-title="AOL"> <img src="@Url.Content("~/images/aolW.png")" alt="icon" /><span>http://openid.aol.com/<strong>username</strong></span></li> <li class="username" title="MyOpenID user name" data-custom-title="My OpenID"> <img src="@Url.Content("~/images/myopenid.png")" alt="icon" /><span>http://<strong>username</strong>.myopenid.com/</span></li> <li class="username" title="Flickr user name" data-custom-title="Flickr"> <img src="@Url.Content("~/images/flickr.png")" alt="icon" /><span>http://flickr.com/<strong>username</strong>/</span></li> <li class="username" title="Technorati user name" data-custom-title="Technorati"> <img src="@Url.Content("~/images/technorati.png")" alt="icon" /><span>http://technorati.com/people/technorati/<strong>username</strong>/</span></li> <li class="username" title="Wordpress blog name" data-custom-title="Wordpress"> <img src="@Url.Content("~/images/wordpress.png")" alt="icon" /><span>http://<strong>username</strong>.wordpress.com</span></li> <li class="username" title="Blogger blog name" data-custom-title="Blogger"> <img src="@Url.Content("~/images/blogger.png")" alt="icon" /><span>http://<strong>username</strong>.blogspot.com/</span></li> <li class="username" title="LiveJournal blog name" data-custom-title="LiveJournal"> <img src="@Url.Content("~/images/livejournal.png")" alt="icon" /><span>http://<strong>username</strong>.livejournal.com</span></li> <li class="username" title="ClaimID user name" data-custom-title="ClaimID"> <img src="@Url.Content("~/images/claimid.png")" alt="icon" /><span>http://claimid.com/<strong>username</strong></span></li> <li class="username" title="Vidoop user name" data-custom-title="Vidoop"> <img src="@Url.Content("~/images/vidoop.png")" alt="icon" /><span>http://<strong>username</strong>.myvidoop.com/</span></li> <li class="username" title="Verisign user name" data-custom-title="Verisign"> <img src="@Url.Content("~/images/verisign.png")" alt="icon" /><span>http://<strong>username</strong>.pip.verisignlabs.com/</span></li> </ul> <div> <label for="openid_username">Enter your <span>Provider user name</span></label> <div> <span></span><input type="text" name="openid_username" /><span></span> </div> </div> <div> <label for="openid_identifier">Enter your <a class="openid_logo" href="http://openid.net">OpenID</a></label> <div> @Html.TextBoxFor(m => m.openid_identifier) </div> </div> </div> <div class="redirection_caption">You will be redirected to <span class="redirection_title">open id provider </span> for your open id verification.</div> <p> <input type="submit" value="Register" /> </p>In the above code first we define a label to display validation messages related to RegisterOpenIdModel. If you remember we have defined RegisterOpenIdModel as the model object to this view. The messages to this validation label are added in the AccountController.cs class using:
ModelState.AddModelError("openid_identifier", "You are already registered with this identifier.");Next we define list of open id providers. Each list item has a class, title and data-custom-title. The class of an item can be direct, openid or username. In case of direct list item user only needs to select open id provider for example Google or Yahoo. The redirection url to these providers is hardcoded into the plugin.
<li class="direct" title="Google" data-custom-title="Google"> <img src="@Url.Content("~/images/googleW.png")" alt="icon" /><span>https://www.google.com/accounts/o8/id</span></li>The second type of class is openid. In this case user is asked to enter complete url of OpenID.
<li class="openid" title="OpenID" data-custom-title="OpenID"><img src="@Url.Content("~/images/openidW.png")" alt="icon" /> <span><strong>http://{your-openid-url}</strong></span></li>The third type of class is username. In this case user is ask to enter user name to the corresponding provider. For example if user selects Blogger as her open id provider then a partial url to blogger is displayed with a text box to enter user name.
<li class="username" title="Blogger blog name" data-custom-title="Blogger"> <img src="@Url.Content("~/images/blogger.png")" alt="icon" /><span>http://<strong>username</strong>.blogspot.com/</span></li>If you notice that we define a data-custom-title corresponding to each open id list item. This custom title is used to indicate the currently selected open id provider. After list item we define two input text controls. First control openid_username appears when user selects open id list item which has username class such as blogger. The second text control appears when user selects open id list item which has openID class such as OpenID. In all cases when form is submitted the complete url value is entered in openid_identifier text control. This value assignment happens in jquery.openid.js file. After two input text controls we define a label which indicates which open id provider the user will be redirected to. We then define a submit button to post data to AuthenticateOpenId function defined in Account controller.
After defining the control we need to add following files into our project.
- Add modified jquery.openid.js in Scripts folder.
- Create Images folder and add all images which come with openid plugin.
- Add modified openid.css into Content folder.
var $this = $(this); var $opendiv = $this.find('div.openid'); var $usr = $opendiv.find('input[name=openid_username]'); var $id = $opendiv.find('input[name=openid_identifier]'); var $front = $opendiv.find('div:has(input[name=openid_username])>span:eq(0)'); var $end = $opendiv.find('div:has(input[name=openid_username])>span:eq(1)'); var $usrfs = $opendiv.find('div:has(input[name=openid_username])'); var $idfs = $opendiv.find('div:has(input[name=openid_identifier])');opendiv variables points to div which contains open id provider list. usr points to openid_username and id points to openid_identifier control. Next we define functions associated with different classes of open id provider list items. The direct function is associated with open id provider list items, such as Google & Yahoo, which contains direct class.
var direct = function () { var $li = $(this); $li.parent().find('li').removeClass('highlight'); $li.addClass('highlight'); $usrfs.fadeOut(); $idfs.fadeOut(); updateRedirectionSpan($li); return false; };In this function we first select list item which is selected. We remove any list item which is highlighted in the open id list and make the current list item has highlighted by assigning highlight class. We hide openid_username and openid_identifier text inputs as in case of direct providers we use urls which are already associated with the list items.
The openid function corresponds to openid list item which contains openID class and requires open id url. The function is similar to direct function as discussed above.
var openid = function () { var $li = $(this); $li.parent().find('li').removeClass('highlight'); $li.addClass('highlight'); $usrfs.hide(); $idfs.show(); $id.focus(); updateRedirectionSpan($li); return false; };As we mentioned, this function is similar to direct function. The only difference is that it shows openid_identifier text input as it requires user to enter this information. The next function is username and it is associated with those open id list items which contains username class.
var username = function () { var $li = $(this); $li.parent().find('li').removeClass('highlight'); $li.addClass('highlight'); $idfs.hide(); $usrfs.show(); $this.find('label[for=openid_username] span').text($li.attr("title")); $front.text($li.find("span").text().split("username")[0]); $end.text("").text($li.find("span").text().split("username")[1]); $id.focus(); updateRedirectionSpan($li); return false; };This function is also similar to both direct and openid functions. It shows openid_username text input as it expects user to enter username for the open id provider. Next we define validation function for input values when submit button is clicked.
function validateInput() { var validate = true; $userNameStatus = $('#UserNameValidation').data('status'); if ($userNameStatus == 0) { $('input#UserName').focus(); validate = false; } else if ($('#EmailAddressValidation').data('status') == 0) { $('input#Email').focus(); validate = false; } else { var $selectedli = $opendiv.find('li.direct,li.username,li.openid').filter('.highlight'); if ($selectedli.hasClass("direct")) { $id.val($selectedli.find("span").text()); } else if ($selectedli.hasClass("openid")) { validate = validateid(); } else if ($selectedli.hasClass("username")) { validate = validateusr(); } } return validate; };In this function we first check if status associated with UserNameValidation is not zero. If status is zero then it means that the chosen user name already exists in the database therefore user must choose another user name. Please recall that we associate status value with UserNameValidation field when we get the response from AJAX call to the VerifyUser function defined in the AccountController.cs. We do similar check for email address. After this we validate open id value. If selected open id list item is direct then the value is extracted from the list item. In case of username openid list item we call validateusr function as mentioned below.
var validateusr = function () { if ($usr.val().length < 1) { $usr.focus(); return false; } $id.val($front.text() + $usr.val() + $end.text()); return true; };This function validates input when open id provider list item with username class is selected. It checks if the username value for the open id is entered in the openid_username text box and returns that value. In case of openid list item we call validateid function as mentioned below.
var validateid = function () { if ($id.val().length < 1) { $id.focus(); return false; } return true; };This function validates openid_identifier text input. It is called when user selects open id provider list item which has openid class. It checks if some url is entered in the text input and returns that value.
The last thing we do is to associate functions with the open id list items as follows:
$opendiv.find('li.direct').click(direct); $opendiv.find('li.openid').click(openid); $opendiv.find('li.username').click(username);
DotNetOpenAuth
As we discussed earlier, OpenId plugin provides user interface to select open id provider. The handling of open id authentication is done through DotNetOpenAuth. We use this library in AuthenticationOpenId function which is implemented in AccountController.cs. This function is the action method of RegisterOpenId.cshtml as shown below:
@using (Html.BeginForm("AuthenticateOpenId", "Account", FormMethod.Post, new{@class = "RegisterOpenid"}))
AuthenticateOpenId receives RegisterOpenIdModel object as an input from the post action. This model object contains username, email address and open id provider. AuthenticateOpenId function first sends a request to DotNetOpenAuth library to authenticate user credentials through selected open id provider. If authentication is successful the function receives the user's open identifier issued by the open id provider through DotNetOpenAuth library. It checks if any user with this identifier is already registered with the system. If no user is registered then the current user is registered with the system and a success message is displayed to the user. Let us see the implementation of AuthenticateOpenId method.
[ValidateInput(false)] public ActionResult AuthenticateOpenId(RegisterOpenIdModel model) { var response = openid.GetResponse(); var statusMessage = ""; //first time this call is for post and response is null. if (response == null) { //save data in session. saveUserInSession(model); Identifier id; //make sure your users openid_identifier is valid. if (Identifier.TryParse(model.openid_identifier, out id)) { try { //request openid_identifier return openid.CreateRequest(model.openid_identifier).RedirectingResponse.AsActionResult(); } catch (ProtocolException ex) { statusMessage = ex.Message; return View("RegisterUser", statusMessage); } } else { statusMessage = "Invalid identifier"; return View("RegisterUser", statusMessage); } } else { //retrieve user from session. user userObj = retrieveUserFromSession(); model.UserName = userObj.name; model.Email = userObj.email; model.openid_identifier = userObj.open_id; //check the response status switch (response.Status) { //success status. case AuthenticationStatus.Authenticated: //Check if this id is already registered in the database. if (VerifyOpenId(response.ClaimedIdentifier).status == 1) { //if user is not register then register this user into the database. userObj.open_id = response.ClaimedIdentifier; saveUserIndb(userObj); Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay; FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, true); string message = "Thank you " + Session["UserName"] + ". You are now registered with the Geostore."; TempData["message"] = message; return RedirectToAction("Index", "Home"); } else { ModelState.AddModelError("openid_identifier", "You are already registered with this identifier."); return View("RegisterOpenIdUser", model); } case AuthenticationStatus.Canceled: statusMessage = "Canceled at provider"; return View("RegisterOpenId", statusMessage); case AuthenticationStatus.Failed: statusMessage = response.Exception.Message; return View("RegisterUser", statusMessage); } } return new EmptyResult(); }
As shown in the above code, RegisterOpenIdView form is posted to AuthenticateOpenId function. It receives user input through RegisterOpenId model object which contains user name, email address and the url of selected open id provider. After receiving the input it calls openid.GetResponse. openid is a static variable and it is defined as:
private static OpenIdRelyingParty openid = new OpenIdRelyingParty();The OpenIdRelyingParty allows a program to become a relying part of an open id provider. When we call openid.GetResponse, it returns authentication response from the open id provider. But at this stage we have not set any open id provider therefore the output of this function would be null. If the response is null we save current object model into session object. The reason why we are calling GetResponse and saving values into session object is due to the fact that AuthenticationOpenId function will be called twice. Once when form is posted and second from DotNetOpenAuth library when it receives response back from the open id provider. So by checking response value we are trying to identify whether our function is called in response to HttpPost or HttpGet. After saving the object model into the session object we validate the url of the open id identifier, if url is valid we create an authentication request using DotNetOpenAuth. DotNetOpenAuth sends the request to open id provider and waits for the response. When it gets the response back it calls back the AuthenticateOpenId function using HttpGet. When this function is called it checks the response value using openid.GetResponse. This time response value is not null so execution starts from else statement of openid.GetResponse. We retrieve user object from the session which we have saved previously. We now check if user's open identifier (response.ClaimedIdentifier) provided by the open id provider already exists into the system. If this identifier exists into our system then it means user is already registered with our system with this identifier. If open identifier does not exist then we save user object into our system and display registration success message to the user. We redirect user to main page of our system. In case if open id authentication at open id provider login page is cancelled or failed then we get respective status codes and we display message accordingly to the user. We have described the working of AuthentcateOpenId function in the diagram below.
![]() |
Flow diagram of AuthenticateOpenId method. |
No comments:
Post a Comment