Tuesday, April 22, 2008

Enhancing the ASP.NET MVC OpenID login experience

In a previous post, I present an example of how to accept OpenIDs for logins on your ASP.NET MVC site.  To keep the sample simple, I left out a feature that people very quickly noticed was lacking: getting registration data from the OpenID Provider (like email and postal address) so the user didn't have to type it in manually.  High demand leads me to follow up with this post on how to add those features.

To get your OpenID login page to automatically get some registration data from the OpenID Provider to make the first login experience for your visitors easy, you need to use the Simple Registration extension.  This extension is included with DotNetOpenId so you have nothing additional to download. 

Simple Registration allows you to ask for any of several predefined fields.  For the sake of this example, we'll ask for email and nickname.  I'll build on the sample I built up in the aforementioned previous post.

In your UserController's Authenticate method, in the "stage 2" area, where you call RedirectToProvider, change the stage 2 code to look like this:

// Stage 2: user submitting Identifier
var req = openid.CreateRequest(Request.Form["openid_identifier"]);
var fields = new DotNetOpenId.Extensions.SimpleRegistrationRequestFields();
fields.Email = DotNetOpenId.Extensions.SimpleRegistrationRequest.Request;
fields.Nickname = DotNetOpenId.Extensions.SimpleRegistrationRequest.Request;

What I've done here is split up the CreateRequest and RedirectToProvider method calls, so that in between them I could construct a SimpleRegistration extension and add it to the request.  If you tested this now, you'd see that during authentication your OpenID Provider would prompt the user for permission to send your nickname and email to the relying party web site.  But your web site doesn't do anything with the answer yet.  Let's fix that.

Under stage 3 in the same Authenticate method, in your switch statement's AuthenticationStatus.Authenticated case, just add a few lines before the RedirectFromLoginPage method call:

var fields = DotNetOpenId.Extensions.SimpleRegistrationFieldValues.ReadFromResponse(openid.Response);
string email = fields.Email;
string nickname = fields.Nickname;
FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);

Of course you'd want to do something useful with the email and nickname like store them in a session or database or something.  That's outside the scope of this post.

But you see it's really quite easy to request this user profile data.  And you can make the code more readable by adding a "using" clause at the top of your file so you can drop all the fully-qualified references to the Simple Registration extension.


  1. What are you using to get your code snippets to appear as they do in the blog post ?