Search code examples
c#.netjwt.net-8.0

Why can't my JWT token be validated after it has been created? .NET 8.0


I am generating JWT tokens in my .NET8 API for issuing on user login.

The logic that handles the token generation can seemingly generate a valid token when tested in jwt.io, however directly after generating the token I attempt to validate it using the same validation parameters that are contained within my program.cs class. and receive the following exception -

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace

It seems like the decoder is unable to find the iss: claim in my payload, although it is definetly present inside of jwt.io

Token code -

    var authConfig = new JwtConfig();
    _configuration.GetSection("JwtConfig").Bind(authConfig);

    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authConfig.Key));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    var userClaims = new List<Claim>
    {
        new(ClaimTypes.NameIdentifier, input.Id.ToString()),
        new(ClaimTypes.Name, input.Name),
        new(ClaimTypes.Email, input.Email)
    };

    foreach (var role in input.Roles)
    {
        userClaims.Add(new(ClaimTypes.Role, role));
    }

    var tokenConfig = new JwtSecurityToken(
        issuer: authConfig.Issuer,
        audience: authConfig.Audience,
        claims: userClaims,
        expires: DateTime.UtcNow.AddMinutes(authConfig.JwtTimeoutInMinutes),
        signingCredentials: credentials);

    var token = new JwtSecurityTokenHandler().WriteToken(tokenConfig);

    // temporary testing
    var handler = new JwtSecurityTokenHandler();
    var validation = new TokenValidationParameters
    {
        ValidIssuer = "https://localhost:7208",
        ValidAudience = "https://localhost:7208",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("82551957-F31C-465F-895F-99DD9B40507C")),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true
    };

    SecurityToken validatedToken;

    var test1 = handler.ReadJwtToken(token);

    var test = handler.ValidateToken(token, validation, out validatedToken);

Solution

  • I ended up getting to the bottom of this through much trial and error.

    The issue seemingly lies in these two nuget packages having slightly different versions.

    Microsoft.IdentityModel.Tokens
    System.IdentityModel.Tokens.Jwt

    Once I made sure these shared the same version, my decoding began to work. It's quite strange how this manifests but hopefully this can help someone else in the future.