SSO in the Age of REST


How does single-sign-on (SSO) look for a representational state transfer (REST) architecture? I began asking myself that question a couple of months ago when people started pointing out to me that LID was very REST-ful.

The SSO idea is typically defined in terms of "applications": sign-on once, use many applications without having to sign-on again. Unfortunately, REST doesn’t know the concept of an application, only the concept of a resource (ie. the thing behind a URL). So does or doesn’t SSO make sense in a REST architecture? This question has puzzled me for a while, but I now think there’s a very simple and elegant answer:

The scope of SSO in a REST architecture is not the application, but the resource.

In other words, instead of introducing an artificial concept of an application into a REST architecture (thereby breaking the idea of REST), we simply do SSO on a per-URL basis.

That, of course, turns out to be a bit of a challenge. Most applications’ sign-on functionality use at least one or two additional screens (and thus URLs): "enter your username here" and "you have been logged on successfully" and stuff like that. But if the scope of SSO is a single URL, how can one reasonably do that?

LID to the rescue ;-) and let me explain how. But before I do that, you should know that we also implemented this scheme and updated our FirstSSO example website accordingly. So you can try it out right there.

Here are the ingredients that we need:

  • One or more resources that need to be access protected, identitied by their URLs.
  • A piece of code that protects access to one or more resources, and that can check whether or not a client is authenticated, and authorized to access this resource (let’s call it the Access Control Script). Given that this is REST, you can think of it as using one Access Control Script per URL, although of course a website with multiple protected resources may want to optimize that and use only one script for many resources. But it is essential to understand that it could be as many scripts as resources, without any further change, otherwise it wouldn’t be REST and SSO but something non-REST-ful.
  • A client that has a LID identity, using a standard browser, no extensions or browser plugins required.
  • A lid cookie and a session cookie.

Here is what happens.

  1. You type in the URL of one of the protected resources into your browser.
  2. The Access Control Script attempts to determine who you are. To do that, it looks at the lid and session cookies, as well as any URL arguments that sign the URL (using the LID clientid, credtype and credential arguments). Given that this is your first visit to the protected resource, none are present.
  3. Given that your identity could not be verified (yet), the Access Control Script does not return the resource, but an HTTP 4.1 Unauthorized error code, with the WWW_Authenticate field in the HTTP header containing the term LID. The body of the returned document should contain a text field that allows you to enter your LID URL.
  4. You enter your LID URL in the returned error document, and submit it to an auxiliary script that redirects you to your own LID, just like in the case of the LID SSO scenario that is defined in the white paper. (Note that from an architectural standpoint, that script is not strictly necessary. It is only there as a user convenience that makes it easy for your to generate signed URLs.)
  5. You authenticate against your own LID management software, and are redirected to the URL of the protected resource, but now with a signature on your URL.
  6. The Access Control Script now can determine who you are by looking at the clientid, credtype and credential arguments to the URL of the protected resource.
  7. The Access Control Script stores your LID URL in the lid cookie, so you do not have to enter your LID URL again when accessing the same resource (it’s up to the site to decide whether or not to use the same cookie for more than one resource; even if it does, that does not change anything). It also issues a session cookie that allows the Access Control Script to skip using the LID SSO protocol for some period of time until the session expires (that’s entirely an optimization step, it would work just fine without the session cookie — except for one thing: it turns out many browsers don’t follow HTTP redirect for included images using the IMG HTML tag, and so we do need the cookie here).
  8. The Access Control Script checks whether or not you (now identified through your LID) may or may not access the resource, using whatever mechanism it desires, such as access control lists. If you are allowed to access the resource, it will return the resource to you.

Isn’t this beautiful? SSO on a per-URL basis, with an optimization (using session cookies) that make this reasonably efficient. Among many other things, that allows you to bookmark URLs to protected resources, and still use SSO to access them.

I’m also beginning to realize that a case could be made to put some of the core LID functionality (such as signing requests and specifying a clientid) right into HTTP. Of course, there would be very substantial pratical difficulties in doing so, but architecturally, I really like the idea that this would be quite straightforward. It indicates that we are on the right track with all of this.