Shortening Open Id & Asp.net MVC

I’ve been working on a project that uses Open Id as the authentication method for public users.  I decided to use the DotNetOpenAuth provider to handle a lot of the grunt work for authentication.  The provider does a lot to simplify the process, but I wanted to make it shorter so I wrote a wrapper around the DotNetOpenAuth code.

You can find the example provided by DotNetOpenAuth for Asp.net MVC here. I am using version 3.4.1, so things may change but hopefully not in a newer version.

Requesting Authentication from OpenId Provider

To submit a request to authenticate all you need is the below code.  The first line builds a claims request to ask the Open Id provider for some pieces of information.  In my example below I am only asking for the user’s email address.  The second line handles making the request and redirecting the user to the provider for authentication.

var claimsRequest = OpenIdHelper.CreateClaimsRequest(OpenIdHelper.RequestInformation.Email);
returnOpenIdHelper.Login(openid_identifier, claimsRequest);

Validating Authentication from OpenId Provider

To validate a request is even easier,  the OpenIdHelper has a ValidateResponse function that will return true if the user is valid or false if not.  If the user is valid the oepnIdUser parameter will be populated with the user’s information.  If there was an error the message parameter will contain the error message to do with what you please.

Authentication.OpenIdUser openIdUser;
string message;

if (OpenIdHelper.ValidateResponse(out openIdUser, out message))
{
    // do some work
}

The below class is what is returned in the first parameter.

public class OpenIdUser
{
 /// <summary>
 /// Essentially the userid
 /// </summary>
 public string ClaimedIdentifier { get; set; }

 public DateTime? Birthdate { get; set; }
 public string Country { get; set; }
 public string Email { get; set; }
 public string FullName { get; set; }
 public string Gender { get; set; }
 public string Language { get; set; }
 public string Nickname { get; set; }
 public string PostalCode { get; set; }
 public string TimeZone { get; set; }
}

Putting it together I have the following actions in my account controller.

[AcceptPost]
 public ActionResult Authenticate(string openid_identifier)
 {
 var claimsRequest = OpenIdHelper.CreateClaimsRequest(OpenIdHelper.RequestInformation.Email);
 return OpenIdHelper.Login(openid_identifier, claimsRequest);
 }

 /// <summary>
 /// Response from OpenId provider telling is user is authentic or not
 /// </summary>
 /// <param name="returnUrl"></param>
 /// <returns></returns>
 [ValidateInput(false)]
 public ActionResult Authenticate()
 {
 Authentication.OpenIdUser openIdUser;
 string message;

 if (OpenIdHelper.ValidateResponse(out openIdUser, out message))
     {
          // do some work
     }
 }

My OpenIdHelper can be downloaded at http://gist.github.com/323195

OpenId Provider Selector

It’s really a matter of preference but I picked the OpenId Selector.  I chose it because it’s simple to use.


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 LogOn
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="HeaderContent"  runat="server">
 <link href="../../Content/openid.css" rel="stylesheet"  type="text/css" />
 <script src="../../Scripts/openid-jquery.js"  type="text/javascript"></script>
 <script type="text/javascript">
 $(document).ready(function() {
 openid.init('openid_identifier');
 });
 </script>
 </asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<!-- Simple OpenID Selector -->
<% using (Html.BeginForm("Authenticate", "Account", FormMethod.Post, new { @id = "openid_form" }))
 { %>

 <input type="hidden" name="action" value="verify" />

 <fieldset>
 <legend>Sign-in or Create New Account</legend>

 <div id="openid_choice">
 <p>Please click your account provider:</p>
 <div id="openid_btns"></div>
 </div>

 <div id="openid_input_area">
 <input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
 <input id="openid_submit" type="submit" value="Sign-In"/>
 </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>
 </fieldset>

<% } %>

</asp:Content>

It could just be me, but I had a strange problem with the plug-in and had to make a minor change to get it to function properly.  In the situation where I have previously selected an OpenId provider, the next time I come to the page and try to select a different provider it still goes to the original provider that was selected.

In the openid-jquery.js plug-in, I had to change line 169 in the setOpenIdUrl function from :

hidden.value = url;

to

$(hidden).val(url);

Well that’s all I got for my first post, hope it’s at least somewhat useful to someone other than me.  Any feedback or suggestions would be appreciated.

In the openid-jquery.js plug-in, I had to change line 169 in the setOpenIdUrl function from :
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s