May 11 2010

Under the covers of OAuth 2.0 at Facebook

For the past three years, the Facebook Platform has been built on top of a session-based authentication system that many developers found complex. In order to make any API calls, you have to understand the details of signature algorithms. It’s a common source of problems for new developers using the Facebook Platform. We have been searching for a way to make it simpler.

The OAuth community has faced similar issues. If a new developer just wants to start using the Twitter API, suddenly they have to understand things like HMAC-SHA256 and how to sign their base string. That is just overkill for a simple web API.

Because of this complexity, I am really excited about the next version of OAuth. OAuth 2.0 largely solves the performance and usability issues from OAuth 1.0a. It relies on SSL instead of signatures as the default way to interact with applications, which means you can play with it in your browser. While there are drawbacks to exclusive reliance on SSL, it is so simple to get started that it can’t be beat for most developers. OAuth 2.0 also splits out flows for different security and performance contexts (i.e., desktop apps vs. web apps vs. mobile apps). That means that when a developer starts coding, they can see exactly what they need and start running.

How did we get here? Last fall, a small group wrote a proposal called OAuth WRAP, which introduced the core innovations of what would become OAuth 2.0 - using SSL and multiple flows. After Bret Taylor implemented OAuth WRAP in Friendfeed, we realized that it lived up to the promise. In the time since, we have been working with Yahoo, Twitter, Google, Microsoft, and many community members within the IETF to produce a new draft.

At f8, Facebook shipped a new Graph API, which relies entirely on OAuth 2.0. In this post, I’ll go into detail about exactly what we shipped and our plans for the future.

The access token is king

The OAuth 2.0 spec is divided into two sections:

* First, you get an access token
* Second, you use the token to access protected resources.

Using a token is the easy part, so we’ll start there.

To use an access token, just append it to the end of a protected resource with the oauth_token parameter. (To alleviate some developer confusion, Facebook also accepts access_token as the parameter name.)

All calls are required to go over HTTPS.

The new Graph API demonstrates how easy it is to get started. You can fetch data about any object on Facebook by hitting https://graph.facebook.com/

Verdict: Topcoder is some hot stuff. Even worth missing the hackathon for.

3 comments


May 22 2009

Logout: the other half of the identity equation

This week, Facebook began accepting OpenID for single sign on. At the Internet Identity Workshop, many people raised a lot of questions about Facebook’s implementation, and in general the relationship between single sign in and sign out. In this post, I’ll argue that sign in is only half the battle; if we want OpenID to represent a complete identity solution, then it needs to support sign out just as robustly as it does sign in.

First, let me define what I mean by “automatic single sign in”. Here’s how it works:

  1. The user first establishes a connection between an identity provider (i.e., Google) and a relying party (i.e., Facebook).
  2. On subsequent visits, if the user is signed into their provider, then the relying party detects that and automatically logs them into their own site.

So then, the user sees something like this on the relying party:

spacer

What does that “logout” link do?

There are three possible choices:

  • Log you out of the current site. (clear cookies on the current domain)
  • Log you out of the current site AND the identity provider. (clear cookies and use cross domain communication to clear the parent)
  • Give the user a choice between #1 and #2.

As I argued last fall, the only logical choice is #2: for it to log you out of not only the current site, but the identity provider as well.

For #1 or #3 (which involve clearing cookies on just the current domain), we leave the user in a logically inconsistent state, which exposes them to security and usability problems.

The contrapositive

One of the basic rules of logic says that if an if/then statement is true, then its contrapositive must also be true.

IF p => q THEN !q => !p

So if we have:

P = “You are logged into the provider”
Q= “You are logged into the relying party”

Then the negation would be:

~Q = “You are NOT logged into the relying party”
~P = “You are NOT logged into the provider”

In English:

If you are NOT logged into the relying party, then you should NOT be logged into the identity provider.

Otherwise, we end up with a contradiction. The user clicks “logout”, and perhaps they even see a logged out page, but when they refresh or navigate away, the relying party will grab the parent’s session and log them right back in.

In short: for relying parties and providers that support automatic single sign in, they need to also support automatic single sign out.

The examples

We can look to the web to see how real sites have implemented this. My favorite example is Google, Youtube, and Blogger. These are all owned by the same company, and if the user sets it up, then they all share the same identity provider (Google). However, I think to most consumers, they are branded sufficiently different that it approximates the world in which the provider and the relying party have no relationship.

Link your Blogger account with Google, then log into Gmail. Then go to Blogger - you’re automatically logged in. Now, click “logout”. You are logged out of Blogger and Google. (Incidentally, you’re also logged out of YouTube, Gmail, and all other Google services).

As another example, go to Citysearch. Log in with Facebook Connect. Now log out, and you are logged out of Facebook as well as all other Connect sites that implement automatic login detection.

Implementation details

Single Sign In

Single sign in can be implemented in different ways. With OpenID, it is accomplished with an immediate mode call. A relying party can do an immediate call either in a background br, or with a full page redirect (if there is only one provider).

In Facebook Connect, the background br request is done automatically by the Facebook Javascript libraries. An application can support single sign in by assigning a callback that refreshes the page when the user is logged in.

Single Sign Out

But, how do we do logout? For Facebook Connect, a site calls FB.Connect.logout(). That will do a background ping to Facebook that clears the user’s current session. It also briefly pops up a screen that says “You are logging out of Facebook.”

spacer

There is no equivalent support in OpenID, but I argue that there should be. I would like to see two request modes in addition to checkid_setup and checkid_immediate.

* logout_teardown: Inverse of checkid_setup, allows user interaction for the logout. If a provider chooses, they could show the user a page before logging them out, and perhaps give the user a choice.
* logout_immediate: Inverse of checkid_immediate, logs out without any interaction. This could be done in a background br or full page redirect.

It would be up to the provider to support one, both, or none of these additional modes.

In the example of Facebook Connect, a provider could display the “You are being logged out” notice via logout_setup.

The choice

But wait, you say! I don’t like this behavior! I don’t want to be logged in and out at will - I want choice to navigate throughout the web.

First, let me assert that most people don’t care that much. They just want it to work. And single sign in / sign out is a conceptually easier model to handle (once we get the kinks out) than having the keep track of accounts across the web. Single sign in is kind of the point of OpenID and related technologies.

That said, there are legitimate reasons why you might not want to support automatic login. For example, Mint.com handles very sensitive data, so may not want to trust in third-party credentials exclusively. Or Netflix, which has its own very developed sense of user identity, including credit cards on file, may choose not to accept single sign on. These companies may find it useful to link with other identities, but single sign on is just not part of the equation.

That’s fine, actually - they don’t have to. But the developer does need to pick a side. If you don’t want to support sign in, then you don’t need to support sign out. But for those sites that DO support sign in, they DO need to support signout. You’re either in the club or not.

Imagine there’s a “single sign in cloud”. When a user logs into their identity provider, they log into the entire cloud; when the log out, they log out of the whole thing. Sites choose whether they join the cloud.

spacer

Let’s review the contrapositive rule. IF a site supports automatic login THEN it must support automatic logout. It’s a choice. If you don’t want to log the user out of the provider when they hit “logout”, then you can’t automatically log them in. You must require them to click a button or enter a password or some such to get in - each and every time.

But regardless, we want to make sure that OpenID supports automatic login and logout, even if it’s not always required.

Update: Shibboleth and Single Sign Out

There’s already been some extensive analysis of single signout within other identity communities. That post makes the very valid point that single signout is much harder than it seems. However, I don’t think that argues that it shouldn’t be attempted, just that we need to watch out and use the right tools.

8 comments   |  tags: OpenID | posted in OpenID, Uncategorized


Apr 15 2009

Making OpenID more useful: let’s detect logged-in state

One of the biggest issues with OpenID is its usability. Many relying parties are currently faced with a difficult choice: how do you let the user know the provider they should be using? Users may be familiar with the brands of Facebook, Google, Yahoo, etc, but if your site doesn’t show it, then it may as well not exist. For the time being, at least, the OpenID brand is invisible (and in fact, sometimes is considered a negative).

As I see it, the fundamental problem we would like to solve is to figure out what are the most likely OpenID providers that the user would like to use? There are a few approaches to this:

  • Show logos for the most popular providers. This is currently a common option, popularized by Janrain’s RPX and numerous other sites. This scales up to maybe 4-8 providers - beyond that, we get into what Chris Messina dubs the “OpenID Nascar”
  • spacer

    Janrain RPX displays icons of various top identity providers

  • Show a dropdown of popular providers. This scales to maybe a few more, but starts to suffer from the value problem. What’s the first element of the dropdown? Do users understand what the “openid” moniker means that sits in front of it? (the answer: nope)
  • spacer

    Ma.gnolia used a dropdown of common providers

  • Let the user type in a url. You can provide a simple textbox, or better yet, a typeahead, in which the user can enter the service provider. The problem is that without prompting, users don’t really understand the value or what to write - in fact, they will type just about anything in there. You can see what this looks like here.
  • spacer

    Blank box offers infinite choice and confusion

The core problem is that we are relying entirely on the user to tell us what their provider is, but we can’t really ask them an intelligent question without explaining the value first. And the catch-22 is that the value provided relies sometimes on the provider! For instance, I may not know what OpenID is or internet identity or whatever, but I just want to log in okay?

To a user of Google products, this is how the interface should look

A solution: detect the user’s provider

Okay, so let’s not just ask the user. Let’s ask the user’s browser, and let it tell us who their provider is. There are a few brainstormed techniques for doing this, none of which is particularly widespread at the moment:

  • One idea that’s commonly suggested but not implemented is to use some strange browser history hacks to determine what sites the user has visited recently. If an OpenID provider appears in the list, then target the message to them. Fantastic!

    While this would work with today’s technology, I think most sites have shied away from it because the information comes via an exploited bug rather than intentional, informed consent.

  • We could build support into the OpenID spec for detecting the user’s current logged-in state. Relying parties could iterate through a whole bunch of possible providers, and if the user is currently logged in, they can show them a login screen. The performance would hardly be as bad as people think - requests can go in the background, in parallel, and you could theoretically query dozens or hundreds of providers within a few seconds (although I admit I haven’t tested it). See more discussion below.
  • We could create a centralized authority or authorities for managing user OpenID provider preferences. People could set a single cookie with their preferred provider, and then every relying party can check that cookie via a cross-domain call. Some Google engineers have initiated some discussion of this based on a similar model used for advertising, but it suffers from a severe chicken-and-the-egg problem. I think that we first need to feel some pain from these other approaches first before everyone gets fed up and moves to a centralized model

OpenID needs a middle state

I think #2 is the best option of the three. OpenID already supports two types of requests- first, modal calls, with a mode of “checkid_setup”, tell the provider to ask the user to login. This is the standard mode that most people are familiar with, and much of the user experience discussion (including my previous post about the popup UI) has focused on it.

The second type of call is triggered with a mode of “checkid_immediate”, and it, well, always returns immediately. This mode is used by a relying party to re-authorize a user that has previously visited the site. When a provider receives an immediate request, it can send only one of two replies:

  1. Yes: Yes, the user is currently logged in, and they have previously authorized your website, so here’s their identifier. (mode is “id_res”)
  2. No: Nope, don’t know anything about them, you have to send them over to find out. (mode is “setup_needed”).

By contrast, Facebook Connect offers more functionality. If an application (relying party) queries the Facebook servers for a given user, it can return three states: returns three states:

  1. Yes, the user is logged into Facebook and they previously authorized your website.
  2. The user is logged into Facebook, but they haven’t authorized your site.
  3. No, we don’t know anything about this user.

That middle state ends up being pretty important. When a site sees it, they can place a Facebook login more prominently than they otherwise would. Also, because the relying party knows the user is already logged in (and so won’t be entering any user credentials), it can issue a nice neat br dialog instead of the heavyweight popup window. Because the popup can’t get blocked or hide behind the window, it is a nicer and less confusing user experience, and it looks better too. (It’s not really a security problem - if the OP wants to collect a password, it can always pop out of the br with Javascript).

There’s currently no way to communicate that middle state via the OpenID protocol. What I would like to see is an additional parameter that’s part of the “setup_needed” mode, which says in effect “the user is logged in, so if you present them with a dialog, it will be an easier experience than with other providers”.

Objection: what if a provider doesn’t want to?

Releasing logged-in state can be an optional feature. There should be a way to return logged-in state within the context of an OpenID transaction. Right now, there’s no standard way to do this, so providers that want to need to invent their own way to release that state.

Of course, the OpenID community has been fighting an uphill battle to even get the basic checkid_immediate call to work. Google, MyOpenID, and many others behave correctly, but even top providers like Myspace, Yahoo, and Microsoft always return a negative response to immediate requests - even when the user is logged in and authorized! We clearly still have a lot of work to do to make checkid_immediate a standard across all top providers.

Nonetheless, the spec should make it possible for providers who WANT to offer this additional state to do so. Just as some providers choose to offer checkid_immediate and others don’t, likewise we should allow those who want to the ability to return a more nuanced reply.

Objection: what if the user is logged into more than one provider?

So let’s say this becomes widespread. A user shows up to a relying party, and the background ping reveals that the user is logged into Facebook, Google, and Yahoo. Now what?

I think this would be a great problem to have. The relying party could present the user with choices if it wanted to, except confident in the fact that the user is familiar with all the choices. Or, a relying party could choose the provider that it has found gives it consistently better data and user experience. Or it could choose based on security preferences. The point is, the interface is still in the control of the relying party, but now the RP has strictly more information to make a better experience for its users.

13 comments | posted in OpenID


Mar 4 2009

A proposal for a conceptual “Open Stack”

Last summer, John McCrea and Joseph Smarr put together a diagram of the “open stack”. The image showed up in numerous talks throughout last year, culminating in an Open Stack Meetup in December. Last week, Marc Canter sent an email asking for thoughts on crafting a new revision to the “open stack” graphic. I’d like to propose a new stack based on the underlying concepts rather than the specific, possibly obsolete technology.

Here’s the open stack graphic from summer 2008:

spacer

The Original Open Stack

Here’s the problem: how do I read this? If I’m an average businessperson or developer who has never read a spec, how do I know what these terms mean? Some of the ideas are in there … ID, Auth, Contacts … but others don’t make any sense. XRDS-Simple? My eyes start to glaze over - that doesn’t seem all that simple. I have to lean over to my friend and ask him what all these things mean.

Technology changes.

The technologies involved here change rapidly. In just the past six months, we’ve added draft specs for PortableContacts, ActivityStreams, OpenID / OAuth Hybrid, and OpenID User Experience. These are all draft specs, which means they will change (some more than others) in the near future. Other specs, like XRDS-Simple, are actively being deprecated in favor of newer versions, like LRDD. And the work is far from done - there will likely be even more specs developed and revved before the whole thing really starts to gel.

Do we really want every version of this graphic to be out of date shortly after it’s released? Or do we want something that is compelling, demonstrates the vision, and gets people thinking about how to do it themselves? We should use the underlying concepts to communicate ideas instead of specific technologies.

spacer

The "Real" Open Stack .. of papers.

For an example of a different approach, I looked at the messaging around Facebook Connect. A developer who’s deciding whether to implement Connect will see the three main benefits: Identity, Friends, and Feed. Sure, it’s much more complicated under the covers, and sure there are some pieces that aren’t covered (lots, actually), but those are the main point

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.