In my Asp.net Core based Web API I would like to use jti (JWT ID) claim to prevent replay attacks while working with JWT (JSON Web Tokens).
As suggested I configured JWT Bearer authentication:
services.AddAuthentication(o =>
{
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateTokenReplay = true,
IssuerSigningKeyResolver = (token, securityToken, kid, parameters) =>
{
// Resolving decryption key
},
TokenReplayValidator = (expirationTime, /*string*/ token, validationParameters) =>
{
// I can check expiration time, but there is no way to check jti
},
};
o.SaveToken = true;
});
In replay validator I can access an expiration time, but there is no way to get jti somehow.
I find it a bit confusing. What common might have a replay attack and an expiration time?
Moreover we have another validator:
bool LifetimeValidator(DateTime? notBefore, DateTime? expires,
SecurityToken securityToken,
TokenValidationParameters validationParameters);
Here I can access the SecurityToken data including jti, but I can't believe that this is a right place for jti-based replay attack validation.
So the question is: how could I get SecurityToken data inside TokenReplayValidator?
UPDATE:
After the @orhtej2 comment, I checked the possibility which he suggested. That works indeed:
TokenReplayValidator = (expirationTime, token, validationParameters) =>
{
var handler = o.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();
var securityToken = handler.ReadJwtToken(token);
var jti = securityToken.Id;
// check replay attack
},
Well, it is a solution, but requires additional token parsing (which cannot be good - unnecessary calculations required on the each HTTP call).
I would like to keep the question unanswered until some better solution found.