OAuth 2.0

This resource explains the basics of OAuth 2.0, the industry-standard protocol for authorization.

OAuth 2.0 is an authorization framework that allows applications such as Facebook, GitHub, and Firstline to gain limited access to user accounts in an HTTP service. It works by delegating user authentication to the service hosting a user account and allowing third-party applications to access that account. OAuth 2 provides authorization workflows for web and desktop applications, as well as mobile devices.

This information resource is intended for application developers and provides an overview of OAuth 2 roles, authorization types, use cases, and workflows.

Access Token

OAuth 2.0 uses Access Tokens. An Access Token is a piece of data that represents the authorization to access resources on behalf of the end-user. OAuth 2.0 doesn’t define a specific format for Access Tokens. However, in some contexts, the JSON Web Token (JWT) format is often used. This enables token issuers to include data in the token itself. Also, for security reasons, Access Tokens may have an expiration date.

Authorization Code

The OAuth 2 Authorization server may not directly return an Access Token after the Resource Owner has authorized access. Instead, and for better security, an Authorization Code may be returned, which is then exchanged for an Access Token. In addition, the Authorization server may also issue a Refresh Token with the Access Token. Unlike Access Tokens, Refresh Tokens normally have long expiry times and may be exchanged for new Access Tokens when the latter expires. Because Refresh Tokens have these properties, they have to be stored securely by clients.

Roles

OAuth defines four roles:

  • Resource owner: The resource owner is the user who grants an application permission to access his or her account. The application's access to the user's account is limited to the scope of the permission granted (for example, read or write access).
  • Client: The client is the application that wants to access the user's account. Before it can do so, it must be authorized by the user, and the authorization must be validated by the API.
  • Resource server: The resource server hosts the protected user accounts.
  • Authorization server: The authorization server verifies the user's identity and then issues access tokens to the application.

From an application developer's perspective, the API of a service fulfils both the resource and authorization server roles. We refer to these two roles together as the Service or API role.

Scopes

Scopes are an important concept in OAuth 2.0. They are used to specify exactly the reason for which access to resources may be granted. Acceptable scope values, and which resources they relate to, are dependent on the Resource Server.

Grant types

In order to obtain an access token the client needs to present a valid grant (credential) to the authorisation server.

If there's one thing that often daunts the newcomer to OAuth 2.0, it's selecting a suitable grant for their application. The choice becomes obvious if you know the type of client (web, mobile, etc) you have.

Grant types and their client type / use case:

  • Name
    Authorisation code
    Type
    Description

    Intended for traditional web applications with a backend as well as native (mobile or desktop) applications to take advantage of single sign-on via the system browser.

  • Name
    Implicit
    Type
    Description

    Intended for browser-based (JavaScript) applications without a backend.

  • Name
    Password
    Type
    Description

    For trusted native clients where the application and the authorisation server belong to the same provider.

  • Name
    Client credentials
    Type
    Description

    For clients, such as web services, acting on their own behalf.

  • Name
    Refresh token
    Type
    Description

    A special grant to let clients refresh their access token without having to go through the steps of a code or password grant again.

  • Name
    SAML 2.0 bearer
    Type
    Description

    Lets a client in possession of a SAML 2.0 assertion (sign-in token) exchange it for an OAuth 2.0 access token.

  • Name
    JWT bearer
    Type
    Description

    Lets a client in possession of a JSON Web Token (JWT) assertion from one security domain exchange it for an OAuth 2.0 access token in another domain.

  • Name
    Device
    Type
    Description

    For devices without a browser or with constrained input, such as a smart TV, media console, printer, etc.

  • Name
    Token exchange
    Type
    Description

    Lets applications and services obtain an access token in delegation and impersonation scenarios.

Authorisation code flow

We will now go through an example of a client obtaining an access token from an OAuth 2.0 authorisation server, using the authorisation code grant. This grant is intended primarily for web applications.

The client needs to perform two steps to obtain the token, the first involving the browser, the second a back-channel request. That's why this series of steps is also called the code flow.

Step 1

  • Purpose: Authenticate the user + Obtain the user's authorisation
  • Request: Front-channel (browser redirection)
  • Server endpoint: Authorisation endpoint (browser redirection)
  • On success: Authorisation code (step 2 input)

Example redirection to the authorisation server:

HTTP/1.1 302 Found
Location: https://server.firstline.sh/login?
 response_type=code
 &scope=read:myapi%20write:myapi
 &client_id=s6BhdRkqt3
 &state=af0ifjsldkj
 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

The authorisation request parameters are encoded in the URI query:

  • response_type: Set to code to indicate an authorisation code flow.
  • scope: Specifies the scope of the requested token. If omitted the authorisation server may assume some default scope.
  • client_id: The identifier of the client at the authorisation server. This identifier is assigned when the client is registered with the authorisation server, via the client registration API, a developer console, or some other method.
  • state: Optional opaque value set by the client to maintain state between request and callback.
  • redirect_uri: The client callback URI for the authorisation response. If omitted the authorisation server will assume the default registered redirection URI for the client.

The authorisation server will then call the client redirect_uri with an authorisation code (on success) or an error code (if access was denied, or some other error occurred).

HTTP/1.1 302 Found
Location: https://www.firstline-customer.com/cb?
 code=SplxlOBeZQQYbYS6WxSbIA
 &state=af0ifjsldkj

The client must validate the state parameter, and use the code to proceed to the next step - exchanging the code for the access token.

Step 2

  • Purpose: Authenticate the client + Exchange code for token(s)
  • Request: Back-channel (client to authorisation server)
  • Server endpoint: Token endpoint
  • On success: Access token, refresh token (optional)

The code-for-token exchange happens at the token endpoint of the authorisation server:

POST /token HTTP/1.1
Host: server.firstline.sh
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code
 &code=SplxlOBeZQQYbYS6WxSbIA
 &redirect_uri=https%3A%2F%2Fwww.firstline-customer.com%2Fcb

The client ID and secret are passed via the Authorization header. Apart from HTTP basic authentication OAuth 2.0 also supports authentication with a JWT, which doesn't expose the client credentials with the token request, has expiration, and thus provides stronger security.

The token request parameters are form-encoded:

  • grant_type: Set to authorization_code.
  • code The: code obtained from step 1.
  • redirect_uri: Repeats the callback URI from step 1.

On success the authorisation server will return a JSON object with the issued access token:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "access_token" : "SlAV32hkKG",
  "token_type"   : "Bearer",
  "expires_in"   : 3600,
  "scope"        : "read:myapi write:myapi"
}

The expires_in parameter informs the client for how many seconds the access token will be valid. The scope parameter what powers the token actually has, as some of the originally requested scope values may have been denied or others, not explicitly requested, granted.

The JSON object can include an optional refresh token, which lets the client obtain a new access token from the authorisation server without having to repeat the code flow.

Access a protected resource

Accessing a resource server, such as a web API, with a token is super easy. The access tokens in OAuth 2.0 are commonly of type bearer, meaning the client just needs to pass the token with each request. The HTTP Authorization header is the recommended method.

GET /resource/v1 HTTP/1.1
Host: api.firstline-customer.com
Authorization: Bearer oab3thieWohyai0eoxibaequ0Owae9oh

If the resource server determines the token to be valid and not expired, it will proceed with servicing the request.

Else, it will return an appropriate error in a HTTP WWW-Authenticate response header.