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.  ↩