March 8, 2022
4 min read time

Two-Minute Tech Tuesdays - JSON Web Tokens

JSON Web Tokens Feature Image

In this week’s episode of Two-Minute Tech Tuesday, we'll introduce you to JSON Web Tokens and demonstrate how to validate them in Varnish Enterprise using vmod_jwt

 

 

In last week's episode, we talked about basic authentication. In this week's episode, we'll introduce the JSON Web Tokens essentials, and how Varnish can handle them.

JSON Web Tokens (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWT operates in an authorization context and is issued after authentication.

See what a JSON Web Token looks like, below. It has a header, payload information, and a signature. The cryptographic signature guarantees the integrity of the payload.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlqcyIsImlzcyI6ImF1dGguZXhhbXBsZS5jb20iLCJleHAiOjE2NDYzMDc0MzEsImlhdCI6MTY0NjMwMDIzMSwibmJmIjoxNjQ2MzAwMjMxfQ.uKkdzlblvUAvd5UDnT4-oGwoptw13b_apm-BY6q8HNM

 

This data is nothing more than base64 encoded JSON. So when we decode the different blocks, this is the information that you will get:

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

{
"sub": "thijs",
"iss": "auth.example.com",
"exp": 1646307431,
"iat": 1646300231,
"nbf": 1646300231
}

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)

 

The header contains the algorithm and the type. If the algorithm contains "HS256" that means the signature is signed with an HMAC signature using SHA256 encoding. It could also be "RS256" if we're using private and public keys.

The payload is a JSON object that contains a collection of claims. These claims are readable by the client and have reserved names such as:

  • The subject (sub)
  • The issuer (iss)
  • The expiration time (exp)
  • The "issued at" time (int)
  • The "not valid before" time (nbf)

You can also add your own claims, but be careful with the size. The bigger you make the claims, the bigger the size of the token over the wire. Also, ensure that these tokens don't contain secrets that shouldn't be visible to the client.

Because the algorithm in our header was HS256, we're using an HMAC signature encoded with SHA256 encoding. We’ll use the header and the payload — both base64 URL encoded — and sign this with a secret key. This key should only be known by the issuer and validator of the token. This guarantees that the data cannot be tampered with.

Besides the JWT being readable by the client to extract information from the claims, it can also be used to get access to restricted resources. You can pass the JWT in an Authorization header by using the Bearer keyword. Below is an example of an HTTP request where a JWT is actually used, allowing the user to understand how Varnish is exactly verifying these tokens.

GET / HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlqcyI
sImlzcyI6ImF1dGguZXhhbXBsZS5jb20iLCJleHAiOjE2NDYzMDc0MzEsImlhdCI6MTY0NjMwMDIzM
SwibmJmIjoxNjQ2MzAwMjMxfQ.uKkdzlblvUAvd5UDnT4-oGwoptw13b_apm-BY6q8HNM

 

vmod_jwt

Varnish can handle JSON Web Tokens through vmod_jwt in Varnish Enterprise. It can issue new tokens, modify tokens, read tokens, and verify tokens. In this blog, we will only read from the JWT. Here is some VCL code:

vcl 4.1;

import jwt;

sub vcl_init {
new jwt_reader = jwt.reader();
}

sub vcl_recv {
if (!jwt_reader.parse(regsub(req.http.Authorization,"^Bearer (.+)$","\1"))) {
return (synth(401, "Invalid token"));
}

if(!jwt_reader.set_key("secret") || !jwt_reader.verify("HS256")) {
return (synth(401, "Invalid token"));
}
}

 

The first thing we’ll do is import the JWT VMOD and initialize a JSON Web Token reader object. This object can be used to parse the JWT that is fetched from the Authorization header — more specifically, the part that sits next to the Bearer keyword. If that is invalid JWT, a synthetic "401 Invalid token" is returned.

Next, we'll check the integrity of the JWT by matching it to the secret key and by checking if the algorithm matches. If that is not the case, again we will return a synthetic 401 with an "Invalid token" message. If it is valid, you can carry on and view the restricted resource.

That was our first introduction to JSON Web Tokens and how vmod_jwt can validate them. Next week, we'll take it up a notch and use Varnish as an authentication gateway to issue JWTs after authentication and verify them to extract information.

varnish_6_by_example_download