RPX OpenID with ASP.NET Webforms and Membership Providers

This evening I started playing around with RPX, the OpenID consolidator from JanRain. I hit a few hurdles along the way, and I thought I would share a little of those experiences with others trying out RPX.

My first step was to download the RXPLib from Google Code, which is a full API wrapper for RPX. It gives you all the method calls you’ll need to work with the RPX API. It is built using the .NET 3.5 Framework, but it worked fine with my 2.0 web application.

The example code provided by RPXNow.com in C# isn’t particularly helpful. It is basically a Windows Console application, which allows you to basically interact with the API. N.B. It requires that you pass parameters to the application, so if you struggle to figure that out, view the project properties and edit the “Command Line Arguments” before you start to run the application in debug mode.

Step right past the console app, and login to RPXNow.com, with any OpenID enabled account and create a website profile. Then use the template created for you, and plug that code straight into your login page of your new website project. Create a call back page to which the authorisation token will be returned to. Add this URL to the script in the place holder (e.g. http://localhost:3456/ReceiveToken.aspx).

Running the web application you’ll get a simple “Sign In” link, which when clicked offers a number of OpenID providers to select. You need to select one, which will redirect you to that provider. Agreeing to the conditions of your provider, you login and are passed back to your token receiving page.

Here is where you implement your tie in to your Membership Provider. It makes a lot of sense to implement a custom Membership Provider, and hook the user into that.

The key areas you want to consider when a user logs into your application using OpenID is:

  1. The user won’t be using a password to login
  2. Does the email address provided by the OpenID provider already exist in your database?
  3. Does the preferred user name passed back also exist?

Because the OpenID user doesn’t need a password to login (although you can offer them one), the CreateUser method of your Membership provider will need to have a default password created for them. Ideally you create a random one and email it to them in their welcome email. This does two things. It allows them to continue logging in with their preferred OpenID, or if they want to, log in with their user name and password.

If the email address already exists in your database (and ideally email addresses would be unique in your provider), you are able to use the “Mapping” feature of RPX. Mappings lost me to start with, because they are not very well explained on the RPX Now website. Quite simply, it allows you to tie up your existing user, to an identity on RPX. After authentication in your Token page, you can call the RPX service to map your local UserId (CustomerId, AccountId, etc) to an identity in RPX. In this way, you can map one of your user accounts to multiple RPX identities.

If the preferred user name returned by RPX already exists in your database, you’ll obviously have to offer the user an alternative user name (unless you use email addresses as user names).

In summary, RPX looks great, and is very simple to implement in a basic format. I’m sure I’ve only just scratched the surface in the few hours I’ve played around with it.

Notably, the basic version of RPX is free, but offers a limited subset of features compared to the premium accounts. One of the issues with the basic version is that your users won’t log in to your website directly, but be transferred to https://youraccount.rpxnow.com. As a result, users may be put off as they are warned constantly about phishing these days, and this looks like a blatant phishing attempt.

Secondly, implementing RPX means that you are putting all of your eggs into one basket. That’s not to say that RPX is going to disappear, but it could.

However, saying all of that, I think RPX is a great idea. Having a single simple control that offers users a great selection of OpenID providers in a easy to understand format is what OpenID needs at the moment.

I look forward to getting something more concrete together soon.

Paging and sorting in a .NetTiers custom stored procedure

If you use .NetTiers as an Application Framework, you’ll have used custom stored procedures in cases where the generic Entity Service Find methods do not offer enough granularity. Specifically, if you have the need to join across database tables, you’ll find that a custom stored procedure is certainly the way to go. However, one of the biggest challenges facing developers is how to develop custom stored procedures for .NetTiers that support paging and sorting.

I have struggled to get a stored procedure that would not just provide the paging and sorting we need, but also would work with .NetTiers so that the correct methods would be generated. So therefore I have put this together to help others.

When .NetTiers generates the output code, it looks for custom stored procedures, based on a given format, and attempts to work out whether the SQL code is returning a list of known objects, or simply a dataset.

Searching, sorting and paging in combination are usually going to imply the use of dynamic SQL queries, but .NetTiers cannot determine the output from dynamically created queries by parsing the SQL code. Therefore, what you’ll find, when you first attempt to create a custom stored procedure, is a new method that returns void. Hence, .NetTiers did not expect any output to be returned from the procedure.

Paging in SQL 2005 is well documented, and with the use of PageIndex, ROW_Number() and RowIndex, you can quite easily perform effective and efficent paging against a 2005 database. For paging we need to know which page we are on, how many results there are, and how many pages of data are possible, given the current search criteria. Most important of all, is the total rows returned. Without this value, the ASP.NET Grid paging or ObjectDataSource / EntityDataSource cannot know how many pages are required to be shown.

My example involves two database tables:

  1. Company: Contain company information
  2. Address: Contains address information

The two tables are linked by the [Company].AddressId to the [Address].AddressId.

Our task is to return a list of companies, by searching on the Address fields. Example:

Return all Companies where the [Address].City=’London’

I have put together a download to demonstrate .NetTiers Custom Stored Procedure Paging and Sorting

This includes table / procedure create scripts, plus an example query. You’ll have to populate the tables yourself. The entire stored procedure is listed below:

If you have any questions or comments, please don’t hestitate to ask.