I have a .NET web server with JWT authentication that checks only the signing key. It’s used by other (internal) servers that need a fixed token that doesn’t expire.
In .NET 6 it worked fine. After upgrading to .NET 8 the requests always return 401 with the error "The signature key was not found".
My authentication config code:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer("external", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = false,
ValidateLifetime = false,
ValidateIssuer = false,
ValidateAudience = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(customKey)),
};
});
The JWT payload is minimal. It is signed with the customKey
and looks something like this:
header:
{
"alg": "HS256"
}
payload:
{
"sub": "100",
"name": "Another Server",
"iat": 1626260955,
"scopes": [
"scope_1",
"scope_2"
]
}
In the logs I get the following message:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7] external was not authenticated.
Failure message: IDX10517: Signature validation failed. The token's kid is missing. Keys tried: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: 'XzATZhHqoi5EL7v3Ol4N3Sbp9y2ZYmyC60I32Bos-0E'. , KeyId: '.
Number of keys in TokenValidationParameters: '1'.
I can’t understand what changed in .NET 8 and how to make it work.
2
Answers
I eventually used an external package
jose-jwt
to perform the token authentication:switch from
JwtSecurityToken
andJwtTokenValidators
toJsonWebToken
andTokenHandler
in .NET 8.you can set
JwtBearerOptions.UseSecurityTokenValidators = true
https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/8.0/securitytoken-events