Wednesday, June 9, 2010

Single Sign On in government: An example, the City of Nanaimo

The City of Nanaimo launched its single sign on portal in on August 27th 2009 with support for only OpenID and its own closed openID provider. As of this writing the closed provider has close to 2000 unique accounts, but this isn't the success. The success is that of the around 10% people that signed up for the first service our emergency notification list (http://www.nanaimo.ca/enotify/) didn't need to create accounts and instead used google or yahoo to login in. Our second service, a community based site to find things to do locally (http://www.secretnanaimo.com) targets a younger demographic and has a 68% non sign up rate, meaning that 68% of users can sign in and contribute content without the need to create an account that they won't remember.

How we did this is by adding a sign in layer to our site that uses existing asp.net technology and the common features of multiple protocols. Our first protocol was OpenID. OpenID is wonderful in that neither party needs to know anything about each other, as long as they both talk OpenID they will work. OpenID supports attribute exchange via a standard extension. I'll leave the discussion of how token based authentication works out of this as I will assume that you already know it or you can read my blog post (http://phansoft.blogspot.com/2010/04/conversation-on-single-sign-on-sso.html) .

On Nananimo.ca once the user tries to access a secured page the IIS server and ASP.NET automatically redirect them to a forms authentication page. In most asp.net rollouts this would be a page with a username and password box but we went a different route, we offer our users choice. The user clicks a logo to login, and eventually we get a login token. We store the token details we want in our Session for example Session["attributes"]["FirstName"] will hold the users first name if we received it. The unique identifier we store in User.Identity.Name the standard location for asp.net authentication. This way any asp.net app we put on our site only needs to know how to use standard authentication to store information for a user.

After a few successful months with only openID we took the opportunity to update our libraries to the newest version of dotnet openauth (http://www.dotnetopenauth.net/) and add two new protocols. Oauth (http://oauth.net/) is a protocol mostly designed for secure API access and this is why twitter uses it, they want to let people sign into a site and have the replying site be able to post to twitter as the person who signed in, even if that person is not currently at the site. All twitter clients do this. We didn't need this functionality but we did want a way to identify the user and Oauth gave us this. When a user authenticates with Oauth we get a unique ID for them that we can use. We add a unique bit to it to make sure there is never overlap with an openID (string TwitterID = "http://twitter.com/statuses/user_timeline/"+ userId.ToString()+ ".xml";) and store that as the username. None of the services had to be updated.

We did the same thing for facebook, using their old login code. They are using Oauth version 2 now but the Oauth library we use does not support it, yet. If some major organization like the Province of British Columbia started using some other system to provide identities such as SAML 1.1 then I would simply add the WIF libraries and accept the login, store it and none of our apps would have to be updated.

If you are wondering about security it's pretty simple we are as secure as the provider that the user chooses. We never store any information back to the login provider other than when the user signs in. So Facebook and Google do know that I have signed up for Nanaimo.ca but they don't know any information about what I filled in or did there. The other question of security is how do we know that Jeff Jacob from blogger is really Jeff Jacob from Nanaimo. Again that is simple we don't, but how do we know that the user that signs up with the username jjacob is the Jeff Jacob he says he is. The answer to both is 3rd party verification. For example on secret Nanaimo we have administrators (employees) that sign in and administer the site. The current system is pretty low demand so I get them to sign in and email me saying they just signed up. I then go into the database and find them and set admin to true. Even if I let them use google (we don't as they have employee openID) I can still find them based on time and the name entered.

For a more large scale system think about paying taxes, the city mails out a letter saying please go pay your taxes, here is your secret number. The user comes to our site and logs in with facebook. The user is then asked for their address and the number. Once they enter this we know that facebook user 876575 is either at 123 boxwood or they stole the mail from 123 boxwood. This is basically the same as our current systems but just removes the need for another username and password.

The last security concern I heard was that if facebook or google gets hacked then they can access all of the user's information on Nanaimo.ca for users that use that system. This is true, but, these are often large companies with experts in security. Also the weakest link is not the provider it is the user. Users pick bad passwords and if you force them to use a good password they will forget it or write it down on a note or worst of all, email it to themselves. A good report to read is http://www.imperva.com/docs/WP_Consumer_Password_Worst_Practices.pdf the most important part is that this site got hacked and 32 million passwords where stored in clear text. Someone got this list and posted it to the internet , 0.9% of the people used the password 123456. Yes that was 29,731 accounts hacked with a single password. You should not expect your users to be any better at picking passwords. The City of Nanaimo uses a hashed and salted password storage system (asp.net standard) that makes common attacks like rainbow tables not work. Even if a user could get this table they would need to generate and test every password and try it against every account. I've done this with one password, for every account and I won't say how many I got into but let's just say that it was more than 0.9%.

At the beginning I mentioned a closed OpenID provider. Not everyone has or trusts their accounts with google, yahoo, aol, myspace, twitter, facebook, blogger, livejournal, myopenid and so on; So we offered a provider for these people. Now the City of Nanaimo didn't want to be responsible for providing sign in services that people could use to sign in and comment on blogs and so on, we have a closed provider. This provider will only pass tokens to sites that we specify so information our citizens enter here is never passed outside of our partner sites.

Short version single sign on made it easier for citizens to access our services, even if they only do it once a year or less. If any governments that want full access to our code are welcome to it.