Generating a JWT in .NET 4.5.2

I recently had to generate a JSON Web Token (JWT) as a response from an login request to an api. The idea is to POST the user's credentials from a mobile app, and to respond with a JWT. The mobile app can then verify that the user has logged in correctly.

A quick introduction to JWT

But let's step out for a moment. What is a JWT exactly? According to jwt.io, a JSON Web Token is

an open, industry standard RFC 7519 method for representing claims securely between two parties.

It's used often as an access token for a client. The client will request access by providing the username and password, and the server will return an access token. A JWT is just an implementation of an access token. The interesting thing about JWT's is that they can contain data. Things you would include in the token are:

  • when the token expires
  • what rights the users has
  • ...

After the client receives the JWT, it should include it with any subsequent request. The server can then decrypt the JWT using the same secret as the client, and by doing that, can see the original contents of the token. If the client tampered with the token, the decryption won't work correctly. This has the benefit that the client can't extend the expiration date, add new rights, etc.

For more information about this, read the introduction on jwt.io and/or this great article.

Generating a JWT

So how can you generate a JWT? First of all, I recommend using an external library like the aptly named JWT.

But in my case, I was stuck on .NET 4.5.2 and the JWT package no longer supports this. In such a case, you can use the System.IdentityModel.Token.Jwt package.

First, we need a header:

var header = new {
    alg = "HS256",
    typ = "JWT"

    var headerPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header));

I'm using JSON.Net to get the string representation of my object, and the Base64UrlEncoder.

Now that we have the header part, we need the payload part. The code is similar:

var payload = new
    userId = user.Id,
    userEmail = user.Email,
    userName = user.UserName

    var payloadPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payload));

Now all we need is a hash of headerPart.payloadPart:

var secret = "my-secret";

var sha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes($"{headerPart}.{payloadPart}"));
var hash = Base64UrlEncoder.Encode(hashBytes);

What this gives us is a string of text containing three parts: the base64url encoded header, the base64url encoded payload, and a hash of those two. Check out the jwt.io debugger for an example. It's also a useful tool to test your implementation.