SPTP: Decentralized Single Sign-On

One thing that has been bugging me, and many others with me, is the need to sign up for every website/service/forum separately. Why not have one super username/password combination that works everywhere and be done with it?

Microsoft has attempted to solve this problem with Passport, but it failed. People don’t trust Microsoft with their personal information. Sun and others have started Project Liberty, but not much has followed from it, for as far as I can see. And the end result will undoubtly be a very complicated API.

Still, the problem bugs me. People don’t trust one company with their personal information. Then I thought, OK, so maybe decentralizing is a solution. People leave their personal information with companies and websites already. Apparently, people trust those websites and companies. It reminded me of Jabber. Jabber is a decentralized instant messaging service. There is no central server where all the contact lists and user data is stored, each user picks or runs its own server where his or her data is stored. For example, my jabber id is zef@12jabber.com. What this means is that I have an account at the 12jabber.com Jabber server, and my username there is ‘zef’. If somebody wants to send me a message, his or her jabber client contacts the 12jabber.com server and tells it that it has a message for user ‘zef’. This way you don’t need a central server. The user id tells you where to send and get information.

Ok, so how can this concept be applied to, say, websites that use an authentication service, like forums? People hate to sign up for each site individually, it would be great if they can easily transfer their profile from one website to the other. I came up with a very simple solution, very similar to what Jabber does. I dubbed it SPTP for now, the Simple Profile Transfer Protocol. This is how it works:

Every application (for example forums) implements a SPTP server. It is a simple script that accepts a username and password and returns the profile data if the username and password match. The software also includes a SPTP client. When somebody attempts to login with a username that does not exist, the format of the username is checked. If it looks like this: someuser@someserver.com, or even: someuser@someserver.com/forums, the software concludes that this is probably a SPTP user. It contacts someserver.com to retrieve the profile data and uses this data to register the user locally on the website. After registration is completed (ideally the user doesn’t even notice this is happening), the user is logged in.

The protocol that I chose for SPTP is very simple and not amazingly secure. On the other hand, profile data is not very secret, so I don’t expect this to be a problem. It is a good idea, however, to allow SPTP login attempts for each user only once very, say, 20 seconds, to avoid people trying to brute force their way in.

The implementation of SPTP is extremely simple. At the end of this post I’ll include a .zip file with a PHP SPTP library that basically has two functions: sptp_exportprofile (to export an associative array of profile data to SPTP XML) and sptp_getprofile (which takes a userid and password and retrieves the profile data for you). All you have to do to use it is implement the automatic registration and server part. I implemented all this in a couple of hours.

SPTP authentication happens as follows: Let’s assume the user Zef@zefhemel.com has attempted to login to a forum where no such user exists. First the file http://www.zefhemel.com/sptp_auth_path.txt is requested by the SPTP library. This file contains the path to the authentication service, for example /sptp/auth.php. Then a POST request is done to http://www.zefhemel.com/sptp/auth.php with two POST fields: username and password. The auth.php script checks the username and the password and, if they are correct, returns a simple XML file which looks roughly like this:

<sptp version="1.0">
   <nickname>Zef</nickname>
   <avatarurl>http://www.fmf.nl/~zef/icon.php?icon.gif</avatarurl>
   ...
</sptp>
The forum then uses this data to register the user locally and logs the user in. That’s it.

One problem remains: which profile fields are there and what are they called? Different kinds of services (and even similar ones) have different profile fields and I think they should be free to add any field they like in SPTP. Fields that the software does not recognize will just be ignored. I think there should be a set of standardized field names, however. Which those would be is open for discussion, some that I can come up with right now: * nickname * realname * avatarurl * icq * msn * aim * jabber * signature

I created a very simple SPTP service and client for demonstration purposes, which you can see and test here. You can download this example and the ad-hoc SPTP implementation I just created here.

It’s all not finished. At this stage I’m mainly interested in input from others. So let me know your thoughts and concerns.

  • The problem is how to implement it with HTTP and HTML when a client-side RSA computation is required. Javascript isn't really an ideal language to do a RSA computation in. It would require activeX, flash or Java.. which isn't really 'complient'.
  • Ok. Well, fine. Just make it reliable enough so that people don't have to ever worry about public and private keys.
  • You don't have that problem, when - as i suggested already - use public/private RSA-like keypairs and you just challenge someone with a random string that can only be decrypted by you (the owner of the private key). There wouldn't be any login box required - as we know it.
  • Not a bad idea, I don't think this would ever work, especially with the password problem.

    The only way I could imagine this would work is that each "login" site only asked for a username (i.e shane@zefhemel.com). That single site could then parse out the server and redirect them to the profile host where the user then types in the password. If successful, the profile host sends a response back to the original site containing a confirmation ID and username. Then some sort of verification code would need to be executed to ensure the confirmation ID was legit.

    Basically, it would work almost exactly like Passport, as login sites don't actually work with the username/password, but without a centralized server.

    Then you have to worry about login box cloaking and all sorts of other fraud activities.
  • Sam Gamyi
    Interesting idea. For the travelling password problem, maybe it would be good that the system generates a unique -random- password for every signup. So if forum "A" is unsecure and some script kiddie is able to know my password in this forum, that would be useless for gaining access to forum "B", since the password would be different for that other forum. (Sorry for my bad english).
  • I guess that every user has their own username on the final application like a message board. But their identity would be a public key; and best would be combined with an username@keyserver, which is easier to work with.
  • Lewis
    What happens with clashing usernames? Surely people could just change data and get any username they want?
  • It can be done way easier and way more secure:

    Everyone should have their own RSA-like keypair.
    The only thing that has to be done to authenticate you is to challenge you to prove that you got the private key alongside the public one.
  • David
    Have you looked at OpenID and Lid yet?
  • Cow
    Sounds very similar to Drupal's distributed login.
  • Zef Hemel
    Manuzhai, about the travelling password, that's very true. I hadn't thought of that...
  • Great idea! If I ever complete the forums from your other idea, this will be part of it :)
  • Another similar proposal: http://xprofile.berlios.de/
  • First: there are already other more simple solutions out there, for example openid.net. Your proposal is interesting to consider from a comparative research point of view, but that's about it.

    Second: I think an important part of having single sign-on is not having to give out my password to every single service I sign up to. In your proposal, my password is travelling through their service. Now, if I also use this account at any other service, the first service has both the username and the password, so anyone from any of the services I am subscribed to can impersonate me at any of the other services.

    Not good.
  • This sounds very, very interesting. I think it would work very nicely. It's easy both for users as for programmers to implement. In fact I think I could implement it in something I'm currently working on. :D
    The only thing I was wondering, the username looks like an e-mailaddress (I presume it isn't), won't this be confusing for some users?
blog comments powered by Disqus