If your website is considering, or has already added, support for federated login with an identity provider, this article describes some best practices to follow to avoid common mistakes (especially if you support more then one identity provider). The first section describes some general best practices. The second section has some notes on handling specific types of users:
We have also provided fully functional sample RP websites to show the user experience for some of the harder scenarios.
1. BEST PRACTICES
Part I - Upgrading Legacy Accounts
No matter what users you support via federated login, one common issue you need to handle is what to do if the identity provider asserts an email address that matches an account that is already in your system. The simplest option is to just create another user account in your database with the same email address. In some cases that just is not possible because it would break how the SaaS application works. However if it doesn’t break the SaaS application, we STRONGLY suggest not taking this approach. Instead, we suggest “upgrading” the legacy account to use federated login as described in Part 2 below.
If you don’t take that approach, users get very confused because Email addresses are the only identifier they understand. They look for email identifiers in the top of websites to help the end user determine if they are logged in at all, and to determine which account (such as work or personal) they are using. If you create multiple accounts with the same email address, even with different usernames, they get confused. If your websites provided a paid service, your help desk can very quickly get overloaded with calls from confused users, or users will just stop using the federated login option. For more details, see the advanced notes.
Part 2 - Linking accounts
If you do decide to “upgrade” the legacy account to use federated login, then another decision you must make is whether to do it invisibly, or to require the user at the browser to prove they own the existing account.
Lets assume for a moment that all the identity providers you support will assert unique email addresses. For example, you might use Yahoo which only asserts @yahoo.com address, and the Google Apps identity provider which only asserts domains hosted by Google, which obviously doesn’t include Yahoo :-)
In that case, you can be sure that any existing legacy account already has a password. So one simple option is to always the require the user to provide the password of the legacy account before linking them. However, if your site provides a “forgot password” flow that involves sending a link to the user’s email account, then the best practice is to invisibly link the accounts instead of requiring the password, assuming the identity provider is asserting Email addresses for which it receives the email.
It is important then when you receive an assertion from one of these identity providers, you check that the email address they assert is on a domain that you know they control. This can be done by having a small whitelist of domain names, and the IDP that controls them. There should be at most one IDP listed for each domain name.
The trickier cases is what happens if you support multiple identity providers that might assert the SAME email address. Unfortunately in that situation, it is possible that an existing account was created using one identity provider, but now another identity provider is asserting THE SAME email address.
If you have read this far, let us warn you that things get very tricky. It is generally better to first start by just adding support for identity providers like Yahoo that won’t create these types of duplications. If you want more details on the tricky details, see the advanced notes.
Part 3 - Legacy passwords
If you do decide to “upgrade” the legacy account to use federated login, then another issue you must handle is what to do with the legacy password on the account. The simplest option is to allow the user to sign in with both their old password, and via federated login. That will confuse some users, but in the worst case they tend to fall back to just logging in with their old password and stop using federated login.
If you want to promote the use of federated login, for example to improve the security of your accounts, then you will need to delete that legacy password. If you do that, then during the upgrade process you should show some visual instructions to the user to remind them of the specific steps they need to use to login in the future. Note that user's whose identity provider offers a strong authentication service (even if it is just protection against password guessing) will be even more likely to want this legacy password backdoor removed, however they very few will be sophisticated enough to think to do so manually, so that is another reason that it should be deleted as a best practice.
Part 4 - Installed apps
Some websites provide not only web-based apps, but also installed apps such as an iPhone App, Android app, Windows/Mac app, etc. In almost all cases, those apps authenticate the user by asking for their password. So if you have users who login via federated login, and don’t have a password, they will be unable to use those apps.
The simplest option is to ask users to provide a password when they create an account, even if they are using federated login. That will confuse some users, but in the worst case they tend to fall back to just logging in with that password and stop using federated login.
If you want to promote the use of federated login, for example to improve the security of your accounts, then you will need to delete that legacy password. However if you still want to support those installed apps, then there are two options. The simplest is to automatically create a machined generated password that they can view from the same page where they would traditionally change their password, and then link to that page from the login UI of your installed apps. That machine password could then be used with these APIs and installed apps. The second option has a better user experience, but requires a lot more work by the SaaS vendor to add code to both their servers and the installed apps. This other option is to use the OAuth standard.
In either of these cases, it is important to stop accepting these OAuth tokens or machine generated password if the user's account is deleted or suspended. If your website is an RP to an Enterprise IDP, then it is important to have a way to learn of any accounts in their domain which have been deleted/suspended, for example if they fired an employee. In the case of Google Apps, this can be done by requesting access to the read-only version of the domain's provisioning API and checking it frequently for accounts that are deleted/suspended. For consumer users, such as an @aol.com user, there is current not standard for how to detect if their account has been suspended (whether for abuse or inactivity).
2. SAMPLE IDENTITY PROVIDERS
The section has notes on handling specific types of users:
Many companies and schools outsource the hosting of their Email to SaaS vendors such as Google Apps. Some of those SaaS vendors, including Google, have started to run identity providers for those domains to support federated login. If you use these Email based identity providers, they will only assert email addresses for the companies/schools they hosts, and there is no chance of the duplication problem occurring during account linking. However, you cannot use the previously suggested tricky of creating a whitelist of those domains because there are millions of them. Instead, you can create a whitelist of SaaS vendors that you want to support. Then whenever you need to decide whether to use federated login for a given domain, you first check your whitelist of domains, and if there is no match, you check with each IDP on your SaaS vendor list to see if they host that domain.
In the case of the Google Apps IDP, the process for performing that check is described in this article, including a method to identify what URL to send the user to via the OpenID protocol to perform the federated login process.
Gmail.com/Googlemail.com email users
If you add support for the Google Apps IDP, your site will indirectly be adding support for the hundreds of millions of users who have @gmail.com addresses. Note that googlemail.com is used instead of gmail.com in some countries, so that domain name may also be provided by end-users. Since Google hosts those domains as well, the check described in the previous section will return a valid result for those domains. Normally users will provide the Apps Marketplace SaaS vendor with the domain name (or email) of their company. The SaaS vendor will then check to see if it is hosted by Google Apps by using OpenID discovery. If it is hosted by Google, then the vendor can redirect the user to the URL provided through the discovery mechanism.
Your website could choose to specifically block the use of OpenID for those domains. However, as a best practice, we do suggest allowing it because it will make it easier for the hundreds of millions of Google Mail users to directly signup for your service.
You should make sure to follow the best practices from SECTION ONE as well as the following two tasks:
The Yahoo and AOL identity providers are similar to the one that works for gmail/googlemail. If you use them properly, they will only assert email addresses those company’s control, and there is no chance of the duplication problem occurring during account linking. Other email providers around the world also starting to offer identity providers.
It is relatively simple to use the Yahoo IDP in this manner, and in fact they host multiple email domains similar to Google Apps, so you could add all of those domains to a whitelist. The AOL IDP is trickier. It is undergoing a lot of changes, but in some cases it allows a user to manually enter the email address that is asserted instead of just asserting the AOL email address of the user. However in some cases the URL it asserts contains the AOL username as a suffix, and that can be used to calculate the user’s email.
Google Account users
Many people are not aware that only half of Google Accounts are gmail/googlemail Email addresses. The rest are other email addresses that users already have setup such as yahoo.com, hotmail.com, aol.com, brownuniversity.com, bakingstore.com etc.
If you want to support the Google Accounts identity provider, then you have to handle all the tricky cases described in “Upgrading Legacy Accounts Part 2 - Linking accounts.”
If you are building a new website, another option is to never build your own login system, but instead ALWAYS use the Google Account identity provider. However, even in that case there are some users who have both a Google Apps account and Google Accounts with the same email address. Google has announced plans to merge those two login systems, and when that is done, it may be reasonable for a new SaaS vendor to outsource their entire login system to Google. However until that time, we suggest not supporting both the Google Apps and Google Accounts identity providers unless you are willing to handle all the tricky situations described in this document.
Microsoft Live users
This situation is very similar to that of the Google Accounts IDP. A large percentage of Microsoft Live users login with emails that Microsoft controls such as hotmail.com, live.com, msn.com, etc. So you can create a whitelist that trusts the Microsoft Live IDP to assert those emails without having to worry about the duplication problem during account linking. The Microsoft Live IDP is undergoing a lot of changes, but currently to get the user’s email address you must request access to the user’s address book and then look for the <owners> entry to extract their email.
Facebook, Twitter, etc.
There are many other identity providers who do not control any email addresses. So the whitelist technique will not work for support them if you want to avoid dealing with the tricky issues of account linking. However some of them do have users select a unique username. Therefore one way to support these IDPs is to ignore the email address they provide, and instead look for that username and prefix it to some domain name you pick like @mail.facebook.com. You can then create an account associated with that fake email address.
However a simpler way to start is to not use these service providers for login, but instead promote the option for your users to link their account to Facebook/Twitter/GoogleBuzz/etc. AFTER they are logged in. That connection process frequently uses technology like OAuth instead of technologies like OpenID. Once that connection is made, you can access their APIs for services such as activity streams, user profiles, address book, etc.
After you have taken this first step, you may find that value of these other APIs is so high that you will be willing to tackle some of the tricky issues described in the first section to enable your site to use these providers for login as well.
Users of SAML enabled domains
Many enterprises run their own identity provider using a technology called SAML. Fortunately these enterprise SAML systems almost always assert usernames/email addresses they control, so you can use the whitelist technique and avoid the tricky issues of account linking.
However if you do support this option, you need to decide whether to allow an employee of that company to link their account to another identity provider, or to even have a password. If the enterprise wants to control how their employees are authenticated, they probably do not want you to allow access via other passwords or other identity providers.
The usability benefits of single-signon and federated login are powerful, but they can also create security and usability problems if implemented without understanding some of the tricky issues involved. Hopefully this article helped provide you with information about some of the known best practices, as well as warnings about situations where the best practices are still being developed.