Visit our archive

OAuth 2 VS JSON Web Tokens:
How to secure an API

A guest post from Simon, developer at Seedbox
(See the original post on his blog).

In this blog post I will be examining two popular approaches to securing an API, OAuth2 and JSON Web Tokens (now on called JWT).

There are many other solutions I could have examined, but for the sake of relative brevity I will focus on these two. Also I am going to assume:

  • You have already built, or are in the process of building, an API.
  • You are now choosing a way to secure this API(s).

Framing the field

Security is something you want to get right. If you need to secure an API right now, I imagine you are worrying about how, exactly, to do it.

First off, worrying about your user’s personal information is a good sign you are doing your job properly. Being skeptical, carefully examining different solutions, are the name of the game here.

Secondly, if you have ever listened to a security expert speak, you know there is no such thing as a perfectly secure system. We need to be thinking in more a subtle way. Security is a world with many facets, just as many trade-offs and is about risk management not risk eradication.

Apples and Oranges

The most important thing to understand when comparing JWT and OAuth2, is that they are not alike. Or even incompatible.

JWT is an authentication protocol

This means it is a strict set of instructions for the issuing and validating of signed access tokens. The tokens contain claims that are used by an app to limit access to a user.

OAuth2 is an authentication framework

OAuth2 on the other hand is a framework, think very detailed guideline, for letting users and applications authorize specific permissions to other applications in both private and public settings.

What’s with the ‘VS’ in the title?

So I need to get clear with you. The only reason I put ‘vs’ in the title was because I know a bunch of people will be searching for a useful comparison, and will probably search for it like that.

The ‘vs’ in the title is misleading, as mentioned, the two are not incompatible with each other. It is possible to have an OAuth2 implementation that issues JSON Web Tokens as an authentication mechanism.

So before we can make a decision about what to implement we need to understand exactly what these solution can provide us with.

What is JSON Web Tokens?

JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS). IETF

JWT is a security standard, that has gained a lot of support in recent times. It is currently in the final stages of becoming an official IETF standard.

The basic idea is that a user will provide a username / password combination to our auth server. The auth server will try and find the user and if the credentials are good will issue a token that the user will send to access resources on servers protected by JWT Authentication.

Here is an example token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

The token consists of three parts:

header.claims.signature

All of these parts are base64 URL-safe encoded to make them safe to add in request urls.

Header

The header simply declares that this is a JSON Web Token and the algorithm used to generate the signature (more details about signing below).

An example:

{
    "alg" : "AES256",
    "typ" : "JWT"
}

Claims

This is the heart of the token. Claims are meant as details about the user that we want to transfer between parties. Maybe we want to authenticate on one auth server and access protected resources another server. Or perhaps our API issues the token and we store the token on a client side app, such as in the browser.

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

Signature

Hang on couldn’t I just Base64 decode the token and alter the claims? Yes you could but the signature would then not be valid. The signature is generated using a private key to hash the Header and Claims. This way only the original token will match the signature. Phew!

This raises an important implementation detail. Only applications that have a private key, ie server-side apps, can trust the claims of the token. It is not advised you put your private key in a browser side application ;).

What is OAuth2?

OAuth2, alternatively, is not a protocol it is a security framework. It details how multiple different roles, users in your system, server side apps like an API, and clients such as websites or native mobile apps, can authenticate with each other.

Unfortunately it would take me a number of blog posts to properly explain OAuth2 but here are the fundamental concepts:

Roles

Both applications and users can be one of the following:

  • Resource Owner
  • Resource Server
  • Client Application
  • Authorization Server

Client Types

A client is something that consumes your API. IT can be one of the following two types:

  • Confidential
  • Public

Client Profiles

There are also client profiles specified by the framework, that describe the kind of application type. They can be:

  • Web Application
  • User Agent
  • Native

Authorization Grants

An authorization grant is a set of permissions given by the resource owner to a client application. They can take the following forms:

  • Authorization Code
  • Implicit
  • Resource Owner Password Credentials
  • Client Credentials

Endpoints

In order for all of us this to work the following endpoints are required:

  • Authorization Endpoint
  • Token Endpoint
  • Redirection Endpoint

A horse designed by a committee?

As you may have already guessed OAuth2 is a pretty massive spec.

The committee, that authored OAuth2, initial intent was to make a strict protocol standard. However the committee could not reach consensus on important parts of the draft so it has never even reached that status.

Protecting your user’s password: You need HTTPS!

Before going in to any discussion of OAuth2 and JWT implementation it is worth taking a moment to point out both these solutions require SSL (https) security. This encrypts the data that is sent along the wire, ie from the browser to the server.

This is crucial because neither solutions provide a way of keeping you user’s supplied credentials secret when in transit. This means anyone snooping on an individuals wifi connection could steel their username and password, when they send it during the initial login!

Some important implementation considerations

Time taken to implement

OAuth2 is a security framework. It’s a details ways of authenticating multiple types of applications in various different scenarios. Because of this there is a lot of material to learn. This is not a fast process.

A very skilled dev I work with, took a whole month to get to a solid understanding of OAuth 2.

Not fully understanding security implementations is NOT an option, therefore there is a significant time investment.

JWT on the other hand is relatively light on conceptual understanding. After a day of reading the specs I felt comfortable starting an implementation.

Risk of implementation errors

OAuth2 is not a strict protocol like JWT. Therefore implementation errors are much more likely. While many libs exist, this is not a magic bullet, as these are still written by individuals who are likely to make errors. Security vulnerabilites are found all the time in many well used libraries.

These risks could be mitigated if you have a large team and could dedicate resources to maintaining your OAuth2 implementation.

‘Social’ signup benefits

In many situations it is convenient to let user’s authenticate using a pre-existing account they have on other larger websites.

If you expect your users to be using an auth provider like Facebook or Gmail, OAuth2 can be a pretty fast and pain free way of adding authentication, by using an existing library.

Conclusion

To conclude, I think it would be useful to spell out the various use cases these solutions should be used for.

The JWT Use Case

Stateless Distributed API(s)

The main strength of JWT is that it handles your application’s user session in a stateless scalable way. The use of embedded claims means we can easily extract user session information on a server that has no access to your system’s user/session db. For a distributed Service Oriented Architecture this can be tremendously useful.

The downside is that if you implement long lived token refresh mechanisms with token blacklists, you lose a little of the inital painfree stateless promise.

Strengths

  • Fast dev time
  • Doesn’t need cookies
  • JSON is mobile friendly format
  • No social login dependency
  • Relatively simple conceptual understanding

Key Limitations

  • Tokens have size limit.
  • Tokens cannot be revoked.
  • This requires tokens to have a short expiration.

OAuth2 Use Cases

As I see it there are two ways that make sense to use OAuth2:

Outsource your auth server

As discussed in the implementation consideration, if you don’t mind your API having a dependency on a third party auth provider, you can simply outsource your auth server.

You register your application with a provider, detailing what access you need from their user’s, like their email address, name, etc.

When user’s land on your site, they will see buttons on your registration page for them to connect with the provider of their choice. The user will be redirected from your site to their provider, asked to allow your app access to their account, then will be redirected back to your website.

Strengths

  • Fast dev time
  • Small amount of code to implement
  • Reduced maintainenance

Big enterprise solution

If you have many APIs needing authentication with different kinds of applications, in both public and private settings, then implementing the OAuth 2 framework probably makes sense.

This will require a small team and considerable dedicated hours, but will result in comprehensive and flexible security for your many different applications. Be warned it is a beast to implement!

If you don’t believe me take a word of warning from the author OAuth who pulled his name from the standard:

To be clear, OAuth 2.0 at the hand of a developer with deep understanding of web security will likely result is a secure implementation. However, at the hands of most developers – as has been the experience from the past two years – 2.0 is likely to produce insecure implementations.

If you have already implemented JSON web tokens, you can use them as your bearer tokens with the claims providing the details of the authorization scopes in your OAuth2 setup.

Strengths

  • Flexible implementation
  • Can work with JWT
  • Extendable to different applications

Further Reading

  • http://jwt.io JSON Web Tokens official, site. Great token debugger, also useful for seeing status of existing libraries in different languages.
  • http://oauth.net/2/ Official Website of OAuth2, great for seeing list of exisiting implementations in different languages.
  • OAuth 2 tutorials Useful overview of how OAuth 2 works.
  • OAuth 2 Spec issues Eran Hammer’s (author of preceeding OAuth standard) views on what went wrong with the OAuth 2 spec process. Whatever your own opinion, good to get some framing by someone who understand’s key aspects of what make a security standard successful.
  • Theory and implementation: with Laravel and Angular Really informative guide to JWT in theory and in practice for Laravel and Angular.

Simon

Comments

comments