JWT Tutorial for Beginners
1. Introduction
JSON Web Tokens are described by the Internet Engineering Task Force (IETF) RFC 7519 as:
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 used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.”
IETF
Acronym fatigue, anyone? In case you’re still on board for some reason JWT is pronounced “JOT”, there that should leave you at least a little more puzzled. In this article I will break this down into “bite size” more easily digestible pieces that hopefully leave you the reader better informed as to what JWT is and how it works.
You see, even though I have used JWT a few times and seen it implemented in several solutions I have worked on. As with most tech projects in today’s deadline driven world I tend to glance over a lot of these types of technologies. Merely fulfilling the API requirements and merrily marching towards the end goal!!! All too often without stopping to smell the binary along the way. This however is a new year (I know it’s March already) and I have promised myself to focus on my art of solution development from a different perspective. To be a better geek and right the wrongs of the acronym enslaved universe.
Table Of Contents
2. JWT Compared
When compared to Simple Web Tokens (SWT) and Security Assertion Markup Language (SAML), there are some great benefits. JWT is arguably more secure than SWT because the latter can only be symmetrically signed by a shared secret implementing the HMAC (Hash based Message Authentication Code) algorithm. SAML on the other hand is XML based and unwieldy. JSON being less verbose than XML thus smaller and much better suited to HTML and HTTP passing.
JWT is pretty much ubiquitous across the internet and particularly suited to web applications and mobile apps too.
2.1 The JWT Lifecycle
2.1.1 Basic Steps
A user logs into an application and provides
their credentials.
The Authentication server authenticates the user
and creates a JWT which is returned to the user.
The user then makes various calls to the application
and passes with these calls the newly created JWT.
The application can use the JWT to verify that the user has in fact been authenticated and proceed with fulfilling the users’ requests.
3. JWT Structure
A JSON Web Token consists of three parts: A Header, a payload and a signature. Let’s take a look.
https://jwt.io offers a great introduction to this process, as well as an excellent breakdown of the three key elements of the JWT: The Header, a payload and a signature.
Let’s take a look.
3.1 Header
The header typically consists of two parts, the type of token which is JWT and the signing algorithm for example SHA512
{ "alg": " HS512", "typ": "JWT" }
The header is the Base64Url encoded.
3.2 Payload
The payload contains the claims. Claims provide information about an entity, typically a user which has been authenticated and other data for example expiration time of the token. There are three types of claims: Registered, Public and Private.
A better technical definition of these categories of claims can be found here https://tools.ietf.org/html/rfc7519#section-4.1
On a cautionary note, when creating custom claim types there is a very real possibility of collisions with existing registered names. Collisions can be avoided by only utilising unregistered claim types. For more information see: https://www.iana.org/assignments/jwt/jwt.xhtml
An example Payload would look something like:
{ "sub": "1234567890", "name": "Ricky Bobby", "admin": true }
The payload is also Base64Url encoded and added to the encoded header.
3.3 Signature
The third and final part of the Token is the signature. To create this, we take the Base64Url encoded header and payload, add a secret, the algorithm specified in the header and sign it.
HMACSHA512( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
The secret should really also in my opinion, be Base64Url encoded, but it is not mandatory. The example here uses a secret for symmetrical signing for brevity. However, JWT can be asymmetrically signed using a suitable algorithm such as PS256 which relies on public/private key pairs.
The end result looks something like this:
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlJpY2t5IEJvYmJ5IiwiaWF0IjoxNTE2MjM5MDIyfQ.k543tZ98ucl_hltjjD9QWR4dCBaSs8d6O6Jp3FEEEjweuB2GZIK4dH0Obbj9preSTbhdrFJ2Wry2dFPcO-wLcQ
4. JWT Security Considerations
JWT is about authorisation. I think this is an important statement to ponder when implementing JWT. Remember the user has already authenticated when they receive their token.
While the asymmetric encryption options do exist and are definitely necessary in some scenarios. We should consider the potential added complexity of certificate management and administration.
4.1 Encryption
While the above example is not encrypted and could be decoded. Any form of token manipulation should be detected by the receiver and the token should be rejected. This is very much implementation dependant.
Here is an excellent article by Sjoerd Langkemper https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/
that demonstrates just some possible vulnerabilities. The pros and cons of symmetric vs asymmetric JWT should be carefully considered.
If the entire session is over SSL/TLS is that not arguably sufficient? Without added complexity. It’s a tradeoff! Also depending on the JWT encryption implementation, there could potentially be an unnecessary performance overhead incurred.
4.2 Expiration
The IETF provides for an expiration value in the JWT specification: https://tools.ietf.org/html/rfc7519#section-4.1.4
The “exp” (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the “exp” claim requires that the current date/time MUST be before the expiration date/time listed in the “exp” claim.
IETF
While tokens can be created without an expiration time. I do not recommend this. We know there are vulnerabilities with JWT implementations and an expiration time coupled with a well thought out session strategy for your particular use case helps mitigate some risks.
4.2.1 Access and Refresh Tokens
A basic guideline for most applications is 15 minutes or less. and re-authentication required every 5-7 days for tokens. You must allow clients to refresh their expired certificates. The shorter lived Token is known as the Access Token and the Longer Lived Token is the Refresh Token.
Access Token Access tokens are credentials used to access protected resources. An access token is a string representing an authorisation issued to the client. The string is usually opaque to the client. Tokens represent specific scopes and durations of access, granted by the resource owner, and enforced by the resource server and authorisation server. The token may denote an identifier used to retrieve the authorisation information or may self-contain the authorisation information in a verifiable manner (i.e., a token string consisting of some data and a signature). Additional authentication credentials, which are beyond the scope of this specification, may be required in order for the client to use a token. The access token provides an abstraction layer, replacing different authorisation constructs (e.g., username and password) with a single token understood by the resource server. This abstraction enables issuing access tokens more restrictive than the authorisation grant used to obtain them, as well as removing the resource server’s need to understand a wide range of authentication methods. Access tokens can have different formats, structures, and methods of utilisation (e.g., cryptographic properties) based on the resource server security requirements. Access token attributes and the methods used to access protected resources are beyond the scope of this specification and are defined by companion specifications such as [RFC6750].
Refresh Token Refresh tokens are credentials used to obtain access tokens. Refresh tokens are issued to the client by the authorisation server and are used to obtain a new access token when the current access token becomes invalid or expires, or to obtain additional access tokens with identical or narrower scope (access tokens may have a shorter lifetime and fewer permissions than authorised by the resource owner). Issuing a refresh token is optional at the discretion of the authorisation server. If the authorisation server issues a refresh token, it is included when issuing an access token (i.e., step (D) in Figure 1). A refresh token is a string representing the authorisation granted to the client by the resource owner. The string is usually opaque to the client. The token denotes an identifier used to retrieve the authorisation information. Unlike access tokens, refresh tokens are intended for use only with authorisation servers and are never sent to resource servers.
4.3 Privacy of Data
The IETF also speaks to concern for privacy of the data in the JWT:
A JWT may contain privacy-sensitive information. When this is the case, measures MUST be taken to prevent disclosure of this information to unintended parties. One way to achieve this is to use an encrypted JWT and authenticate the recipient. Another way is to ensure that JWTs containing unencrypted privacy-sensitive information are on transmitted using protocols utilising encryption that support endpoint authentication, such as Transport Layer Security (TLS). Omitting privacy-sensitive information from a JWT is the simplest way of minimising privacy issues.
IETF
Simply put, if you want to avoid another potential security issue, do not put sensitive data in the token.
The IETF provides much more information regarding security considerations here: https://tools.ietf.org/html/rfc6749#section-10
5. JWT Best Practices
The IETF provides a draft specification on JWT best practices: JSON Web Token Best Current Practices https://tools.ietf.org/html/draft-ietf-oauth-jwt-bcp-00#section-3
This document provides us with the current best practices and is a very valuable tool. While the document is very technically detailed I strongly recommend at least a once over for anyone looking at a JWT implementation.
I have summarised a list of best practices from the site here:
- Cross-JWT Confusion
- Perform Algorithm Verification
- Validate All Cryptographic Operations
- Use UTF-8
- Validate Issuer and Subject
- Use and Validate Audience
- Use Explicit Typing
As with all things security related, weaknesses will be identified and fixes applied. It is always good to know you have at least covered the well known issues and countermeasures from the outset. In some instances not all the issues here will apply to your implementation such as cryptography if you are using secret based tokens.
6. JWT Tutorial – Conclusion
JWT is a great approach to securing web applications. Whether or not you use full blown encrypted certificates or simple signed certificates. The implementation will potentially deal with sensitive data and the access thereof. As such you need to handle with care.
When combined with powerful third party libraries such as AUTHO https://auth0.com/ for Authentication. it is a powerful security tool for the developer. However as shown JWT is about much more than simple Authorisation and I urge you to research best practices and ask the right questions when considering your next JWT implementation.
There is a plethora of tools out there available to help us ensure the security of our tokens and some of them are tried and tested.
TIP: You wouldn’t really consider creating your own encryption algorithm for obvious reasons (although in some cases you might need to), so make your journey easier, by leveraging what’s available in fulfilling a “best practice” implementation.
JWT implemented incorrectly, arguably just adds unnecessary overhead and little to no security benefits at all. When implemented correctly however, it provides a light weight, scalable, responsive token based security solution.
I am hoping that this article provided you, the reader with a much clearer understanding of what a JWT is comprised of and more importantly when and how it is used as part of your security strategy when building your next application.
7. Download the Source Code
This was a JWT tutorial for beginners.
You can download the full source code of this example here: JWT Tutorial for Beginners
Jason Web Tokens should be JSON Web Tokens.
Thanks for picking that up Robert. It has been rectified.
Securing API with JWT
I understand the concept of JWT(Json Web Token) and how it works for REST APIs.
The thing is, in order to get the token, a user needs to authenticate(user and password), right?
How is that authentication secured and verified?
I know securing the channel(using HTTPS) is the first thing, but, if the following communications needs to be secured, authorized and authenticated; How is it possible the authentication part is not strongly secured?
Am I missing anything? Or is there anything else to secure the authentication step?