We recently upgraded all our dependencies to the latest version.
We are using .net 8. it was a small minor upgrade.
Ever since we did this upgrade we cannot manually verify jwt tokens any more.
The normal process still works where we provide the jwt token as a header and allows the system to function as normal.
We have a few external calls that happen which needs to jwt token to be passed in as a query param.
I can take the token and pop it into jwt.io or jwt.ms and i can see the expiry date is set for 7 days from now.
But if i try to validate the token manually using JwtSecurityTokenHandler.ValidateToken we get the following error:
Microsoft.IdentityModel.Tokens.SecurityTokenNoExpirationException: ‘IDX10225: Lifetime validation failed. The token is missing an Expiration Time. Tokentype: ‘System.IdentityModel.Tokens.Jwt.JwtSecurityToken’.’
If i read the token with JwtSecurityTokenHandler.ReadJwtToken i can access everything in the token, but the ValidTo property is set to 0001-01-01.
this is the method we use to create the token:
private string CreateJwtToken(List<Claim> claims)
{
var eCDsa = LoadPrivateKey(_tokenProviderConfiguration.EcdPrivateKey);
var securityTokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Issuer = _tokenProviderConfiguration.IssuerFormat,
Audience = _tokenProviderConfiguration.AudiencesFormat,
Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(_tokenProviderConfiguration.ExpirationMinutes)),
SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(eCDsa), SecurityAlgorithms.EcdsaSha512),
IssuedAt = DateTime.UtcNow
};
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
var securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
return jwtSecurityTokenHandler.WriteToken(securityToken);
}
this is our method to manually validate tokens as well as the parameters:
public bool IsTokenValid(string token)
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Provided token is null or empty.");
var tokenValidationParameters = GetTokenValidationParameters();
JwtSecurityTokenHandler jwtSecurityTokenHandler = new();
try
{
ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
return validatedToken != null && validatedToken.ValidTo > DateTime.UtcNow;
}
catch (Exception)
{
return false;
}
}
public TokenValidationParameters GetTokenValidationParameters()
{
var eCDsa = LoadPublicKey(_tokenProviderConfiguration.EcdPublicKey);
return new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = false,
ValidIssuer = _tokenProviderConfiguration.IssuerFormat,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new ECDsaSecurityKey(eCDsa),
ClockSkew = TimeSpan.FromSeconds(5)
};
}
An example token i created (stripped out all the private data)
eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MzBjZjZiOC02ZDU4LTRhODQtOTVhNy0yZmRmZjgyOGEyMTEiLCJhdWQiOlsiaHR0cDovLyoubG9jYWxob3N0OjQyMDAiLCJodHRwOi8vKi5sb2NhbGhvc3Q6NDIwMCJdLCJpc3MiOiJodHRwczovL2FwaS5sb2NhbGhvc3QiLCJuYmYiOjE3MTk4MjM2ODMsImV4cCI6MTcyMDQyODQ4MywiaWF0IjoxNzE5ODIzNjgzfQ.AB4rmG-j61DoGC49K-8ZYLbU6sHcwIxI7Vwh2Zp5w4v15X6p9Y2AhQXmGB7BAGVbVW4rWlGAHPzjMzBW6PDCDQTrAa8V1y0X1fAHRpXRsoKtS4cfnSEpRVQnVYj96SKn-UcGVqtZ2AOzGrsPG4Nwz-HXnN2Sdi5bTUUoDaSPn8ZdCyJe
Example from Jwt.IO, showing the expiry date
This is causing a massive headache for us now as clients cannot download their orders.
Thanks in Advance
I have tried stripping out all the extra data we normally add, and the problem still persists.
Arno Botha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.