Tuesday, April 25, 2006

Simple Single Sign-on Scheme

Single sign-on, or SSO, has become the Holy Grail of enterprise web applications and indeed, just like the mythical quest taken up by knights in medieval times, so there has yet to be found a unified standard to allow users to easily login across trusted web sites. The battleground is littered with the corpses of failed initiatives such as Microsoft's Hailstorm. The Liberty Alliance has churned out a number of PDFs but that seems to be the extent so far of their effort. On the open-source side, LID shows a lot of promise but without any major corporate sponsors, it's difficult to judge how successful it will be.

So lacking a working foundation to go on, I decided to strike out on my own. My requirements were simple in that a user would not have to create a separate account, the login procedure would not be a hindrance and above all it had to be secure. Too often in my dealings with vendors I've seen login schemes that easily allow a malicious user to spoof another user's identity and masquerade as somebody else on the site. With this lesson in mind, I went about detailing how it would all work.

We'll need to make some assumptions first. This scheme requires at least two entities. Entity A is the main organization, the one that holds all the users' account info. Entity B is a vendor that has agreed to interface with Entity A so that users will not have to create a second account to utilize Entity B's services. We must also assume that a user logs in with a user ID and password to access Entity A's site. That user ID must be unique and can be an email address or something auto-generated. As well, Entity A must have a service visible to the outside that can validate a user with their ID and password. The easiest method would be to have a web service that checks against an LDAP, RDBMS or some other data store.

The process begins when a user logs in to Entity A's site with their user ID and password. Once validated, a string is generated containing the user's ID and any other meta information Entity A may want to pass along to Entity B. This string is then encrypted using a key that has been pre-shared with Entity B. The resultant encrypted string is put through a Base64 encoding function and then URLEncoded to ensure that no characters are lost. This string is appended to a URL pointing to Entity B's site using an agreed upon CGI variable. This URL can be displayed as a link which the user can then click on.

Upon arriving at Entity B's site via the URL, the appended string is put through a reverse process (URLDecoded, Base64 decoded, decrypted using the same pre-shared key) and from that the user ID and any other attached meta information is made available. At this point, the user should see only an input field requesting their password. The other data can be put into hidden form fields which will be passed along when the user submits the form. When that form is submitted just the user ID and password will be passed back to Entity A but this time to a published web service to authenticate against. If the web service returns success, then the user is logged in. Otherwise, the user is routed back to Entity B's site but with an appropriate error message.

Simple really was the theme of this SSO implementation. Though it lacks the features of some of the more mature setups, it does have the advantage of being relatively easy to deploy. As well, the requirement that a user resubmit their password at Entity B's site means it can withstand a replay attack. And provided that employees at Entity A do not have direct access to users' passwords, they would not be able to login as another user either. You could increase the security even further by changing the pre-shared key every 90 days though even with the most basic Triple DES encryption a brute force attack would be impractical.

This scheme has been in production for over a month now on our member portal with no complaints or reported errors. This feat would not have been possible though without the help of some talented individuals. My colleague John K. proved invaluable when it came to brainstorming on this issue. And were it not for Mark H. at Workmode, my point man at the vendor, this project would not have gotten off the ground. Lastly, the encryption functionality was provided courtesy of DevX.com and was extremely easy to implement and use.

Please feel free to comment on this or email me if you have any questions.


Robin Wilton said...

A couple of brief comments, Sean:

First, you say -

"As well, the requirement that a user resubmit their password at Entity B's site means it can withstand a replay attack. And provided that employees at Entity A do not have direct access to users' passwords, they would not be able to login as another user either."

OK, but you're therefore making the judgement that letting both A and B know your ID and password is better than the inconvenience of having to set up an account at B. That's a possible use-case, for sure, but the original SSO problem Liberty set out to solve was where the user does have accounts and both A and B, and wants SSO between them *without* having to divulge the IDs and passwords to both service-providers.

Do any of your current users use your implementation for SSO to their bank? How would the bank feel about their account-holders divluging their online banking password to a third party website?

Second, you say that Liberty has produced a few PDFs and that's about it:

With respect, when adoption of your idea reaches a billion identities, I'm sure the Liberty folks would be delighted to hear about it...

Sean said...

Before implementing this admittedly light-weight SSO solution I looked into what the Liberty Alliance had to offer. I was impressed by the breadth and scope of what it was attempting but for many organizations, mine included, it was unbearably complex and there was no working demo I could show to management. Having worked in the J2EE world for some time before moving to Ruby on Rails, I have a keen eye for the monster known as software by committee. I can only hope that when the Liberty Alliance is ready, they release a product that effectively meets their laudable goals.