Security

OAuth 2.0 in a nutshell

Let’s say you’re developing a SOA application. The user interface is a website that needs to be accessible from the public internet. You are using service composition in the UI, so you have JavaScript components from each service deployed in the UI. These components talk with their corresponding Web API over HTTP. Since the Web APIs are public facing, they’re sitting in the DMZ, so you need to secure them.  In this blog post series I’d like to give a high level overview about the de facto standard for authorization – OAuth 2.0 and the emerging standard for federated authentication – OpenID Connect.

Authentication & Authorization

First, let’s define what authentication and authorization mean:

Authentication is the process in which we validate that someone is who they claim to be. Usually you can authenticate by providing at least one of the following factors:

  • something you know – a password or a pin
  • something you have – a certificate or an RSA token
  • something you are – finger print

Authorization is the process through which we check the permissions that someone has. Although this can be modeled in multiple ways, it can be viewed as a matrix with subjects per lines, resources per columns and actions in cells.

OAuth 2.0

If we’re talking about API authorization, we need to also discuss about the delegated access model. The end user delegates access to his resources hosted on the web API to the client – the website. If we don’t want to pass the user’s credentials to the client and the APIs, then OAuth is a good choice. OAuth is an authorization protocol that can be used to enable limited access to private resources for 3rd party apps.

Actors

These are the main roles defined by the OAuth protocol:

The resource owner is, as the name says, the owner of the private resource, which means he can grant access to it. Many times the resource owner is the end user.

The resource server hosts the resources. If we’re talking about securing a web APIs – that’s your resource server.

The client is the application that wants to perform actions on the resources on behalf of the owner. A website that is consuming data from web APIs is a good example for a client.

The authorization server grants access to the protected resources to the clients, with the approval of the resource owner.

OAuth - Code - General

Tokens

Since the purpose of OAuth is to enable the resource owner to grant access to his resources without sharing his credentials, OAuth uses token-based authorization. A token is a unique identifier issued by the authorization server and used by the client to associate the request with the resource owner.

Access Token

OAuth 2.0 relies on access tokens which grant permission to a client to access protected resources on behalf of the resource owner. An access token usually has an expiration date and a scope – what actions can the client perform on the resource (e.g. read or write). I should be opaque to anyone except the Authorization Server – that means that even though it might contain meaningful data, you should not try to interpret it. An access token might also have an audience, which means the token is issued for a specific client and it can be used against a specific set of resource servers.

The token type is one of the extensibility points of OAuth 2.0 since you can define your own token type. OAuth 2.0 defines two main token profiles: bearer token profile and MAC (Message Authentication Code) token profile.

The bearer token is like cash – anyone who has it can use it. The MAC token on the other hand is like a credit card – in order to use it you need to authorize it with your signature. You never pass a MAC token over the wire, while bearer tokens need to be transmitted. This means you always need to use TLS with bearer tokens. Because it’s more difficult to implement the MAC token profile, the majority of OAuth 2.0 implementations use the bearer token profile.

Refresh Token

OAuth also defines an optional refresh token. This can be used to obtain a new access token. The lifetime of a refresh token is much longer compared to the lifetime of an access token. This means that if an access token is compromised, an attacker can use it for a limited amount of time (usually it’s in the order of minutes).

The Valet Parking Analogy

Eran Hammer used the Valet Parking analogy in order to explain  the purpose of OAuth. Many expensive cars these days have an additional key, known as a valet key, that gives limited access to the car: you can drive only a limited distance and you can’t open the glove box or the car’s trunk.  This is what OAuth is for: when you (the resource owner) drive your car (the protected resource) to a hotel and the valet parking attendant (OAuth client) wants to park your car, you don’t want to hand him your master key (username and password), which would give him unlimited access to your car. So you give him the valet key (the access token) which gives him very limited access to the car, so he can park it.

Registration

OAuth requires that clients to register to the Authorization Server so that it can identify valid API requests. After a client registers, it will receive a client ID – which is public – and a client secret – which should be kept private.

Authorization Flows

OAuth 2.0 introduced the concept of an authorization grant. A grant represents the resource owner’s approval and it can be exchanged for an access code. The authorization grant is another extensibility point of OAuth 2.0 as it enables multiple types of client to use the the protocol. OAuth 2.0 defines 4 primary grant types: authorization code, implicit grant, resource owner password credentials and client credentials.

Authorization Code Grant

The Authorization Code (or Server Side flow) was designed for server applications. After getting approval from the resource owner, the authorization server returns an authorization code to the client through a query string parameter. Then, using the client ID and client secret, the client can exchange the authorization code for an access token through a server side call. This means that the access token is never revealed to the resource owner, which ensures confidentiality of the access token and it’s less likely that the access token is hijacked by malicious JavaScript code in the browser.

This grant type can be used to issue refresh tokens too, so it’s a good fit when requiring long lived access. This implies that the client application will store the refresh token, which might make it more vulnerable.

OAuth - Code - Code

Implicit Grant

The Implicit grant type was designed for client side applications – like a JavaScript app running in the browser. Since the entire application code is accesible, the client secret cannot be stored in the application. This is why an access token is returned immediately through a hash code URL fragment after the resource owner authorizes the client in the first step. This flow does not support refresh tokens, so you need to request a new access token after it expires.

OAuth - Code - Implicit

Resource Owner Password Credentials Grant

In this flow, the resource owner passes his username and password to the Authorization Server, in exchange for an access token. Since the client must know the user’s password, it is recommended to implement this flow only in highly trusted clients – like official mobile apps.

OAuth - Code - Resource Owner

Client Credentials Grant

In this flow, the client is the resource owner. He must pass his credentials in order to retrieve an access token. This grant type should be used when the client – usually an API – needs to access resources that he owns, like a database or a storage service.

OAuth - Code - Client

Endpoints

An endpoint is simply an HTTP resource that is used as part of an authorization flow. OAuth defines 3 endpoints: 2 authorization server endpoints – authorization endpoint and token endpoint and 1 client endpoint – the redirect endpoint.

The authorization endpoint is used in order to interact with the resource owner and retrieve the authorization grant (code) for the client. This endpoint must ensure that the client is authenticated.

The token endpoint is used to exchange the authorization grant for an access token. It is used in all flows, except the implicit one, which issues an access token directly from the authorization endpoint.

The redirect endpoint is used to redirect the resource owner’s browser back to the client application. Tokens are also passed to the client through query string parameters or hash code URL fragments.

Profiles

OAuth 2.0 can be extended by implementing custom grant types and/or token types. These are some of the profiles built on top of the core framework in order to accommodate new use cases:

The SAML 2.0 Bearer Assertion Profile is used to exchange SAML assertions for access tokens. This is mostly useful in enterprise scenarios when the organization already uses SAML for federated authentication.

The User Managed Access Profile enables the resource owner to define and manage multiple access policies for his protected resources in a single place – the authorization server.

The Chain Grant Type Profile enables a resource service to use the received access token and act as a client to another resource service in a chained manner.

The Token Introspection Profile allows clients to request metadata regarding a token, for example to find out if a token has expired or what is its audience.

The Token Revocation Profile can be used to revoke a token.

The Dynamic Client Registration Profile allows clients to register with an authorization server and retrieve their client ID and secret dynamically.

OAuth 1.0 vs OAuth 2.0

OAuth 2.0 isn’t an upgrade of OAuth 1.0. Actually, they are pretty different on a conceptual level.

OAuth 1.0 is a concrete security protocol which relies on signatures in order to provide a high degree of security. This makes OAuth 1.0 a complex protocol that can be difficult to implement. Also, OAuth 1.0 didn’t reach a high adoption rate because it wasn’t extensible – it provided a single flow which aimed to accommodate all client profiles.

OAuth 2.0 is a security framework so, by definition, it’s extensible. Its two main extensibility points are grant types and token types. Also, OAuth 2.0 dropped the use of signatures and cryptography and relies on TLS for securing data in transit, which makes it transport dependent. OAuth 2.0 sacrifices security for extensibility and ease of implementation. Eran Hammer resigned from his role as lead author and editor for the OAuth 2.0 specs and disagrees with the design decisions made for OAuth 2.0.

Conclusion

OAuth 2.0 is the de facto standard for API security. You should now know the basics of this framework and when you should use a certain authorization flow. In the next blog post we will discuss about authentication through OpenID Connect.

If you want to find out more about OAuth 2.0, you can check these resources: