Try it yourself with our free Jwt Decoder tool — runs entirely in your browser, no signup needed.

How to Decode JWT tokens in C#

How to Decode JWT Tokens in C#

JSON Web Tokens (JWT) have become a widely adopted standard for securely transmitting information between parties. As a C# developer, you may encounter JWT tokens in various scenarios, such as authentication and authorization. Decoding these tokens is crucial to extract the payload and verify the authenticity of the data. In this article, we will explore how to decode JWT tokens in C#.

Quick Example

Here's a minimal example to get you started:

using System;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;

public class JwtDecoder
{
    public static JwtSecurityToken DecodeToken(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
        return validatedToken as JwtSecurityToken;
    }
}

This code uses the System.IdentityModel.Tokens.Jwt NuGet package, which can be installed via the Package Manager Console:

Install-Package System.IdentityModel.Tokens.Jwt

Step-by-Step Breakdown

Let's dissect the code:

  1. We import the necessary namespaces:
using System;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
  1. We create a JwtDecoder class with a DecodeToken method:
public class JwtDecoder
{
    public static JwtSecurityToken DecodeToken(string token)
    {
        ...
    }
}
  1. We create a new instance of JwtSecurityTokenHandler, which is responsible for handling JWT tokens:
var tokenHandler = new JwtSecurityTokenHandler();
  1. We call the ValidateToken method, passing the input token and a null validation parameters object. This method verifies the token's signature and extracts the payload:
var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
  1. We cast the validated token to a JwtSecurityToken object, which provides access to the payload:
return validatedToken as JwtSecurityToken;

Handling Edge Cases

Here are some common edge cases and how to handle them:

Empty/Null Input

public static JwtSecurityToken DecodeToken(string token)
{
    if (string.IsNullOrEmpty(token))
    {
        throw new ArgumentException("Token cannot be null or empty", nameof(token));
    }
    ...
}

Invalid Input

public static JwtSecurityToken DecodeToken(string token)
{
    try
    {
        var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
        ...
    }
    catch (SecurityTokenException ex)
    {
        throw new ArgumentException("Invalid token", nameof(token), ex);
    }
}

Large Input

public static JwtSecurityToken DecodeToken(string token)
{
    if (token.Length > 2048)
    {
        throw new ArgumentException("Token is too large", nameof(token));
    }
    ...
}

Unicode/Special Characters

public static JwtSecurityToken DecodeToken(string token)
{
    try
    {
        var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
        ...
    }
    catch (ArgumentException ex)
    {
        if (ex.Message.Contains("Invalid token"))
        {
            throw new ArgumentException("Token contains invalid characters", nameof(token), ex);
        }
        throw;
    }
}

Common Mistakes

Here are three common mistakes developers make when decoding JWT tokens in C#:

Mistake 1: Not validating the token signature

// Wrong
var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

// Correct
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);

Mistake 2: Not checking for null or empty input

// Wrong
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);

// Correct
if (string.IsNullOrEmpty(token))
{
    throw new ArgumentException("Token cannot be null or empty", nameof(token));
}

Mistake 3: Not handling exceptions properly

// Wrong
try
{
    var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

// Correct
try
{
    var principal = tokenHandler.ValidateToken(token, null, out var validatedToken);
}
catch (SecurityTokenException ex)
{
    throw new ArgumentException("Invalid token", nameof(token), ex);
}

Performance Tips

Here are three performance tips for decoding JWT tokens in C#:

  1. Use the ValidateToken method: Instead of using the ReadToken method, use the ValidateToken method, which verifies the token's signature and extracts the payload in a single step.
  2. Use a caching mechanism: If you need to decode multiple tokens with the same validation parameters, consider using a caching mechanism to store the validated tokens.
  3. Avoid unnecessary object creation: Avoid creating unnecessary objects, such as JwtSecurityToken instances, when decoding tokens. Instead, use the ValidateToken method to extract the payload directly.

FAQ

Q: What is the difference between ReadToken and ValidateToken?

A: ReadToken reads the token without verifying its signature, while ValidateToken verifies the signature and extracts the payload.

Q: How do I handle token validation exceptions?

A: Catch the SecurityTokenException exception and throw a new ArgumentException with a meaningful error message.

Q: Can I use this code with .NET Core?

A: Yes, this code is compatible with .NET Core 2.1 and later versions.

Q: How do I decode a token with a custom validation parameters object?

A: Pass the custom validation parameters object to the ValidateToken method.

Q: What is the maximum size of a JWT token?

A: The maximum size of a JWT token is not specified, but it is recommended to keep it under 2048 characters to avoid performance issues.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp