In today’s interconnected web ecosystem, all communicating parties must ensure secure authentication and data exchange. One popular and reliable method for transmitting information between parties in a compact and verifiable manner is through JSON Web Tokens (JWTs). It’s a proven way of implementing Bearer Token Authentication and securing APIs. In this article, we will examine the key elements that enable us to decode a JWT in .NET.

To download the source code for this article, you can visit our GitHub repository.

Let’s begin.


VIDEO: Decode a JWT in .NET.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!


Understanding JWT

JWTs consist of the Header, the Payload, and the Signature, separated by a dot. Let’s explore its structure:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjlBNkIyOTEwRDYyQ0UwMzc5RjNCREI1MjBBNTc1RTIyIiwidHlwIjoiYXQrand0In0.eyJpc3MiOiJodHRwczovL2RlbW8uZHVlbmRlc29mdHdhcmUuY29tIiwibmJmIjoxNzAwNjU0MjQ0LCJpYXQiOjE3MDA2NTQyNDQsImV4cCI6MTcwMDY1Nzg0NCwiYXVkIjoiYXBpIiwic2NvcGUiOlsiYXBpIl0sImNsaWVudF9pZCI6Im0ybSIsImp0aSI6IkUwRjYyQTA1MjM1RDY4MzdFNjcwNzExRTY1NDFDMjlEIn0.pFpzXr3jMKBYpB1JC6bq04xMyJ5gsWCq45TjO2SH44Ai6Fnic-5hn_IAYGaRPTu8dqwZjH0aBZd2UEmpvQs3WgWUANHbqG7fOAmaQQ7z3T8RRBWj5kpD6tlXmsACJAVZZl4Yra8cvrf0gacC9UHQtX9WRF51y7NeG2ZWIPq5OB4jzKvObDmcoujQgjaRRX-j7pMcpAWGxG_VMjVR9kqeOlhsfOeg3K8STIsZ46XvPhTD5CtK9j5HyYWCpadFGlpmskT8E_lBwrCGdJQae8EEO7-NllRLLaTTqz52KsT-Mhyolu7MMZy1lm58NXhv4g5_rzLbKelTWnbsBJzu-phdkg

The Header includes metadata about the token, such as the key id (kid), type (typ), and the signing algorithm (sig). Within the Payload, there are claims, which are statements about the user or additional data. The Signature ensures the JWT’s integrity by encoding the header, payload, and a secret key. All this information is encoded in Base64 format.

jwt.io is a convenient tool that allows us to view the stored information in the JWT. Let’s use it to examine the decoded information of the token we just saw:

JWT Decode

The tool decodes all the properties of the JWT separated as Header, Payload, and Signature sections. Next, let’s explore how to decode JWTs with .NET code.

Decode JWT With .NET

First, we need to install the required NuGet package to get this working:

dotnet add package System.IdentityModel.Tokens.Jwt

Our first task is to convert the token in the string format to an instance of a JwtSecurityToken class in the  System.IdentityModel.Tokens.Jwt namespace:

public static JwtSecurityToken ConvertJwtStringToJwtSecurityToken(string? jwt)
{
    var handler = new JwtSecurityTokenHandler();
    var token = handler.ReadJwtToken(jwt);
    
    return token;
}

First, we create an instance of a JwtSecurityTokenHandler. Next, we use the ReadJwtToken() method to read and parse the input JWT string, which converts it into a JwtSecurityToken. The method then returns the acquired token. Once we obtain the token, we decode it as the next step:

public static DecodedToken DecodeJwt(JwtSecurityToken token)
{
    var keyId = token.Header.Kid;
    var audience = token.Audiences.ToList();
    var claims = token.Claims.Select(claim => (claim.Type, claim.Value)).ToList();

    return new DecodedToken(
        keyId,
        token.Issuer,
        audience,
        claims,
        token.ValidTo,
        token.SignatureAlgorithm,
        token.RawData,
        token.Subject,
        token.ValidFrom,
        token.EncodedHeader,
        token.EncodedPayload
    );
}

We extract essential information from a provided JwtSecurityToken. Through a series of operations, we retrieve key details from the token. Initially, we capture the keyId stored within the token’s Header, followed by acquiring the Issuer information directly from the token itself. The Audience data, representing recipients, is retrieved and formatted into a list for easy access.

Then, we extract Claims, converting them into a list of tuples containing the claim Type and its corresponding Value. To determine the token’s expiration, we retrieve the expiration date (ValidTo). Additionally, we capture the signing algorithm employed for the token’s validation (SignatureAlgorithm).

Also, we fetch the RawData directly from the token. We then attempt to gather the Subject information, which may sometimes be empty, especially in scenarios like “client_credentials” (Machine to Machine) grants.

Furthermore, we retrieve the token’s validity start date (ValidFrom), capturing the moment the token is considered valid. We also acquire the header and payload in the token’s encoded payload (EncodedHeader and EncodedPayload, respectively).

In summary, we systematically gather crucial details such as key id, issuer, audience, claims, expiration, signing algorithm, raw data, subject, validity start, header, and payload from the provided JWT, consolidating them into DecodedToken type for further processing or analysis.

Conclusion

To ensure secure data transmission and authentication in modern applications, developers working with .NET must take essential steps. Firstly, they must gain an understanding of the structure of JSON Web Tokens (JWTs), as this is crucial. Secondly, they need to leverage suitable libraries. Thirdly, it’s essential to configure validation parameters. By implementing these measures, developers can establish robust mechanisms for decoding and validating JWTs seamlessly. This will empower them to ensure secure data transmission and authentication, making their applications more reliable and secure.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!