OAuth 2.0 and the road to hell

Eran Hammer who, until a few days ago, was the main editor of OAuth 2.0 has written this very damning blog post about the protocol

http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/

I’ve been following the working group for about a year now and there has been an awful lot of bickering and mindless discussion.

As I’ve stated already, I’ve spent the last few weeks working on a brand new library that implements the current spec (draft 30) and I do feel myself agreeing with some of his points:

  • Yes the specification mess, I’ve highlighted and sticky noted the printed document to death and the flow between different sections is really bad
  • Some new features such as refresh tokens are overly complicated and don’t benefit the protocol, and it means clients now have to maintain access token state added to complexity
  • Just reading the spec you can tell how much it has been influenced enterprise – many features are very open ended so that you bolt OAuth onto something else (or something else onto OAuth)
  • Bearer tokens over SSL/TLS by themselves are bad and I think signatures need to come back
    • Basically if I steal someone’s access token I can use that wily nilly, however with signatures the entire request is signed with the client’s secret key so unless the secret key is leaked you can’t just use access tokens by themselves

I disagree however that the protocol (in it’s current state) is complicated, they’ve done great work at making it a 3 (or 4) legged protocol to just 2 legs and everyone agrees that bit of the protocol has been done well.

In terms of his suggestion that alternatives to OAuth that are outside the reach of the IETF might crop up I’m quite interested in this and if something crops up I’ll stick my nose in, and if one doesn’t then I’d be interested in having a go in writing one myself as an output of Linkey.

In terms of the extension documents (which include the assertions (SAML) extension, i don’t know enough about SAML to make any sort of informed opinion about this, however I’ve also still yet to see any public implementation of it.

Quick update

I’ve not blogged in a little while so I thought I’d give an update on what is happening with Linkey.

First I’ve been working with Paul in the library to capture (videos and screenshots) examples of poor user experience accessing various resources including electronic journals and databases, printers, and users’ library accounts.

I’ve also been trawling through last year’s NSS results to find examples of where students particularly struggled to access IT and library resources. I will then produce visualisations of these.

It is important to capture these examples so that hopefully by the end of the project we can show how we’ve improved the situation.

This week we launched our Ezproxy service [note: requires authentication] which has already improved accessing a number of resources including articles from the American Chemical Society, EBSCO Publishing and Oxford University Press.

I’ve also been working away at the new PHP OAuth library. Originally this was just going to be code for implementing an authentication server and a resource server, but now it is also going to include client code too thanks to Phil Sturgeon offering to integrate his existing code. As a result we’re going to have a lean and mean library that can help anyone work with any aspect of OAuth 2.

How OAuth 2.0 works

The following sequence describes how the OAuth 2.0 web-server flow works. The web-server flow is the most common OAuth flow which most implementations support.

Before we begin there is some terminology that needs to be understood:

  • Resource owner (a.k.a. the User)
    An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
  • Resource server
    The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
  • Client
    An application making protected resource requests on behalf of the resource owner and with its authorisation. The term client does not imply any particular implementation characteristics (e.g. whether the application executes on a server, a desktop, or other devices).
  • Authorisation server
    The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorisation.

The web-server flow

1) The client redirects the user to the authentication server with the following information

  • The client’s ID (client_id)
  • A redirect URI where the user will returned to after they’ve authenticated with the authentication server and approved the client (redirect_uri)
  • The type of response that the client accepts (response_type)
  • A list of data which the client wishes to access on behalf of the user (scope)
  • A state parameter which is an anti-CSRF token (state)
	HTTP/1.1 302 Found
	Location: https://auth-server.tld/authorise?response_type=code
	&client_id=6BZF3wT52E7PaIlF1luRrKM4LMfkl649
	&redirect_uri=http://client.tld/signin/redirect
	&scope=basic,contacts
	&state=84Y632oM3j

2) The user signs into the authentication server and, if they haven’t already, approves the client to access their data. The user is informed which data the client wishes to access (defined by the scope parameter). If the user has already approved the application the server will check if the scope parameter matches that of the previous request and if it doesn’t will ask the user to sign in again.

3) The authentication server redirects the user back to the client (based on the redirect_uri parameter) with an authorisation code and the anti-CSRF token in the query string

	HTTP/1.1 302 Found Location: http://client.tld/signin/redirect
	?code=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&state=84Y632oM3j

4) The client then exchanges the authorisation code for an access token by authenticating itself with the authentication server

	POST http://auth-server.tld/access_token HTTP/1.1
	Content-Type: application/x-www-form-urlencoded
	client_id=6BZF3wT52E7PaIlF1luRrKM4LMfkl649
	&client_secret=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&redirect_uri=http://client.tld/signin/redirect
	&code=Al0wQaeTYsji97oRWk2l6Y940wdca3J2
	&grant_type=authorization_code

5) The authorisation server will perform the following validation:

  • Check that the client_id and client_secret are valid parameters
  • Check that the [authorisation] code matches the client_id and the redirect_uri

If the parameter pass the validation checks then the authentication server will respond with the access token that the client needs to access the user’s data. The server may also include a refresh token in the response.

	HTTP/1.1 200 OK
	Content-Type: application/json;charset=UTF-8
	Cache-Control: no-store
	Pragma: no-cache
	
	{
		"access_token":"2YotnFZFEjr1zCsicMWpAA",
		"expires_in":3600,
		"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
	}

Accessing resources

Once the client has the access token it can then make requests to the resource server for the user’s data

	POST http://resource-server.tld/user/details HTTP/1.1
	Content-Type: application/x-www-form-urlencoded
	
	access_token=2YotnFZFEjr1zCsicMWpAA

Angst against OAuth

Tim Bray, a developer at Google wrote in a recent blog post that he believes:

The new technology coming down the pipe, OAuth 2 and friends, is way too hard for developers; there need to be better tools and services if we’re going to make this whole Internet thing smoother and safer.

As someone who has been working with OAuth 2.0 for almost 18 months now I disagree with Tim’s position that OAuth 2.0 is “way too hard” for developers. The web-server flow essentially is a simple two step process:

  1. A redirection from the client to the authorisation server
  2. A POST request to the authorisation server to swap the authorisation code for an access token

I find it hard to believe that those two simple steps are too much for developers to implement in their applications.

It’s true that OAuth 1.0a was a pain to implement – just take a look at Twitter’s OAuth 1.0a guide to see how complicated it is in compared to the v2.0 flow I’ve described above – however as more and more service providers offer OAuth 2.0 endpoints I believe that developers will realise how easy it is to actually implement.

What is OAuth?

The OAuth website describes OAuth as:

An open protocol to allow secure API authorisation in a simple and standard method from desktop and web applications.

Essentially OAuth is a security protocol that enables users to grant third-party access to their web resources without sharing their passwords.

OAuth grew out of discussions between developers from Twitter and Ma.gnolia who wanted to authorise desktop applications to access their services. A working group was formed in 2007 to draft a proposal for an open standard. Developers from both Google and Yahoo also contributed to this work.

The first OAuth Core 1.0 draft was released in late 2007. In 2008 it was decided that the Internet Engineering Task Force (IETF) would adopt the specification to allow wider discussion and further standardisation work.

A minor revision (OAuth 1.0 Revision A) was published in June 2008 to fix a security hole. The OAuth 1.0 Protocol was published by the IETF OAuth Working Group in April 2010 as RFC 5849.

A number of Internet companies and services adopted OAuth 1.0 but it was considered too much of a pain in the arse to work with by developers because it involved complicated signatures being passed around and there were too many requests between clients and services.

In May 2010 work began on version 2.0 of the OAuth protocol. Version 2.0 is not backwards compatible with OAuth 1.0a and focuses on developer simplicity. It also features more flows to allow the use of OAuth in more situations, as well as extensions to the core protocol to enable interoperability with assertion based protocols such as SAML.

OAuth has been adopted by many large Internet services and companies, here are some to name a few:

  • Google (v2.0)
  • Yahoo (v1.0a)
  • Twitter (v1.0a and v2.0[1]))
  • Github (v2.0)
  • Microsoft (v2.0)
  • Foursquare (v2.0)
  • Salesforce (v2.0)
  • Facebook (v2.0)

We have been using OAuth 2.0 here at the University of Lincoln since late 2011 where we investigated using it for the Total ReCal project so that students here at the university could access their event data. Our implementation was based on some work I’d already been doing in the area based in my own time.

We currently have over 30 application using OAuth to interact with our data sets including the Student Union website, the staff directory, Orbital, and four 3rd year student final projects.

In October 2011 I spoke at EduServ’s Federated Access Management conference about how OAuth works and how we are using it. The slides for this presentation can be found at https://speakerdeck.com/u/alexbilbie/p/introduction-to-oauth.

During the Linkey project I’m going to be redeveloping my CodeIgniter OAuth 2.0 server to a be a framework-agnostic Composer package. I’m also going to be adding support for the bearer extension and the assertions extension.


  1. Currently on Twitter Connect supports OAuth 2.0 using the XXX flow.  ↩

Plan for w/c 09/07/12

The plan for this week (w/c 09/07/12) is as follows:

  • Continue re-architecting my original OAuth server code into a composer library that is framework agnostic – the code is available at https://github.com/lncd/oauth2server/tree/develop.
  • Meet with Paul Stainthorp to understand (and watch) the difficulties user face access library resources.
  • Following the above, capture videos and screenshots of users accessing library resources so we can hopefully show at the end of the project how things have improved.
  • Write a blog post entitled “What is OAuth?”
  • Response to Tim Bray’s blog post on “OAuth 2 and friends, is way too hard for developers” to show how easy OAuth 2 actually is compared to OAuth 1.0a.
  • Announce the Linkey project on the OAuth mailing list.
  • Finish the project plan for JISC.