I’ve almost completed my test of RPX with ASP.NET webforms. My first pass attempted to mix the ASP.NET Membership with RPX, and although I got it working, it felt like a fudge. I wrote a custom Membership Provider, and pushed the RPX identities through it, but somehow it just felt dirty.
In fact I’ve never liked the ASP.NET Membership model, and it has always bugged me. It forces you into a model of username over email address (where email addresses are always more memorable and unique) and never seems to deliver a profesional finish. Now OpenID is here to stay, making registration and login so simple, the Membership model feels slightly wonky. It still has its place, especially in intranet applications with Windows / LDAP, but as an internet model it just sucks. Look at any of the big popular websites out there, and then imagine the CreateUserWizard. I know it can be customized, but hell, they could have made it just a little bit more snazzy.
Membership rant aside and to cut a long story short, I dropped the custom Membership Provider. I cut everything down to the bare minimum, and aimed to produce a skeleton website, that uses RPX as an authentication mechanism, and would be my base framework for any new sites I build.
I used two tables, the first stores our base Account information, and it’s dead simple, containing only an AccountId and a Nickname. The second table is AccountIdentity and stores identities for each Account, and one Account can be associated to multiple identities.
Why multiple identities? Well, users often have more than one OpenID provider. They might have a Google Account and YahooID, they might also have a Myspace or a Facebook account. Any of these can be used as an OpenID, and the user might want to tie these all together into one Account with us, or not – the choice is theirs.
Our AccountIdentity table stores all of the common information provided by the RXPAuthenticationDetails, delivered after a callback to the RPX Service.
In more detail – when a user clicks on the sign-in button, provided by the easy to use login controls RPX Now gives you to get started, you give RPX a Url on your website, to which the user will be redirected to after they have authorised your website with their OpenID provider. In this authentication stage you’ll do a couple of things:
- Check if the user is already logged in. If so, we are going to check the existing AccountIdentity table to see if this RPX Identity already exists for this user, and if not, we’ll add it.
- If the user is not logged in, we check the RXPAuthenticationDetails to see if a “LocalKey” was provided. If so, we’ve already mapped this RPX Identity to an existing user account. We need to load the appropriate account, check the identity does indeed match, and then log the user in.
- Finally, if the user is not logged in, and no LocalKey was provided then this user is probably new. We should still check the existing AccountIdentity table to make sure the identity doesn’t exist, and then we’ll create a brand new account, and store the new associated identity.
Then we use the Account.AccountId as the Forms Authentication ticket, and sign the user in. That’s it, nothing more complicated.
So, what about Roles, and Profiles you ask? Well that’s to come…