Implementing OpenId with ASP.Net MVC

OpenId is awesome. I first discovered it when I started using StackOverflow.com. OpenId allows users to create a single account that they can use to login to any website that accepts it. All the user has to do is create an account with an OpenId provider (I happen to use www.myopenid.com). The nice thing about this for developers is that it completely offloads all the managing of users, profiles, passwords, authentication, and other headaches associated with developing a site to someone else.

Here is a diagram and an explanation of the sign-in process.

Get a Provider
The first thing you need to do is to setup an account with an OpenId provider. RpxNow has a “Basic” package for free that has everything you need to get started. They also allow users to sign-in using their existing accounts fomr places like Facebook, AOL, Google, and several others. This is awesome if you don’t want your users to deal with the hassles of createing yet another account.

Add a Login Link
Now we need to provide a link to allow the user to sign-in to our site. Add the following code in the <Head> section of your page.

<script src="https://rpxnow.com/openid/v2/widget" type="text/javascript"></script>
<script type="text/javascript">
<!--
        RPXNOW.token_url = "http://mydomain.com/Account/Login";
        RPXNOW.realm = "myRpxAccountName";
        RPXNOW.overlay = true;
// -->
</script>

Then add the Login link to your page:

<a class="rpxnow" onclick="return false;" href="https://myRpxAccountName.rpxnow.com/openid/v2/signin?http://mydomain.com/Account/Login">Login</a>

A couple of things to note here. The "myRpxAccountName" is the developer account you get when you register with RpxNow, and the "http://mydomain.com/Account/Login" link is where the authentication token gets sent (you'll see this part below). Also, the only thing really needed for the link to work is for it to have a the "rpxnow" class assigned to it.

Setup Controller Action
Once the user logs in through they're OpenId provider we get an authentication token returned to us. It gets sent to the "http://mydomain.com/Account/Login" link we specified above. Using the "Default" routing of {controller}/{action}/{id} we can setup our controller like this:


public class AccountController : Controller
{
     // Matches http://mydomain.com/account/login
     public ActionResult Login(string token)
    {

    }
}

Get User Information
The most complicated part of the process is sending the token to the Rpx Webservice and getting the user profile information back. The good news is they give us the code to help use get started. I've modified the code slightly which you can download at the end of this post.

public ActionResult Login(string token)
{
     XElement profile = Rpx.GetProfileData(token);

/* Example of returned data.
    <rsp stat="ok">
      <profile>
        <displayName>Micah</displayName>
        <identifier>
           http://micahlmartin.myopenid.com/
        </identifier>
        <name>
          <givenName>Micah</givenName>
          <familyName>Martin</familyName>
          <formatted>Micah Martin</formatted>
        </name>
        <preferredUsername>
         
micahlmartin
        </preferredUsername>
        <url>http://micahlmartin.myopenid.com/</url&gt;
      </profile>
    </rsp>*/
   

    //Determine if user is new and if so then create
    //a new record in the database and map the recordId
    //to the openId
    if(UserIsNew)
       Rpx.Map(openId, userId);

    //Login user
    FormsAuth.SetAuthCookie(username, rememberMe);
    return RedirectToAction("Index", "Home");
}

Essentially what happens here is we call into the Rpx webservice and get the profile data back. You then determine if the user already exists in the database. If not then create a new record and pass the new record Id along with the OpenId (in my case http://micahlmartin.myopenid.com/) into the Rpx.Map function. Now all future login requests for the user will contain a <primaryKey> node with recordId of the user. Last thing to do is just call a FormsAuth function to finish the login.

Conclusion
All told it probably took less than 45 minutes to get it implemented. The longest part was understanding the work flow, and even that wasn't bad. I hope this has been helpful. You can download the Rpx class file Here Rpx. You will need to rename it from .doc to .cs.

kick it on DotNetKicks.com

About these ads

4 Responses to Implementing OpenId with ASP.Net MVC

  1. mikeinmadison says:

    Check out my post at http://www.mikecomstock.com/post/RPXNow-MVC-Project-Template.aspx. It does almost exactly what you are saying and provides a ready to use Visual Studio project template.

  2. micahlmartin says:

    Awesome. Thanks for sharing.

  3. Amber says:

    It was nice to see your blog.Just Keep Writing!

  4. RPX is NOT an OpenID Provider. OpenID Providers issue OpenID identifiers to their users so users can log into “relying party” web sites. Google, Yahoo and MyOpenID are Providers. RPX is a third-party independent system that makes it easier to write a relying party web site.

    Just terminology.

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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: