У меня есть приложение ASP.NET core 2.2, которое предоставляет конечную точку API.Эта конечная точка защищена простым токеном JWT, который заботится только о предмете, сроке действия и подписи (SHA256 с использованием общего секрета).
Когда я вызываю конечную точку из основного клиента .net, она работает нормально.
Я сейчас пытаюсь вызвать тот же код из клиента Delphi, но сервер отклоняет эти токены, и я не могу понять, почему: оба токена выглядят одинаково для меня, и они оба проходят тест проверкиat jwt.io
Код проверки токена на стороне сервера:
private static TokenValidationParameters GetValidationParameters(byte[] key)
{
return new TokenValidationParameters()
{
ValidateLifetime = true,
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
// Cutom validity validation
DateTime current = DateTime.UtcNow; // get a single value for "now"
// check if the token expiration is valid and if it doesn't expire
bool value = (expires.HasValue) && (notBefore.HasValue) && // both "expires" and "notBefore" must be set
(expires >= current) && // "expires" must not be in the past
(expires <= current.AddMinutes(5)) && // "expires" must not be any further than 5 minutes in the future
(notBefore <= current); // notBefore must be in the past or present
return value;
},
RequireExpirationTime = true,
// the token has no audience or issuer so ignore these
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKey = new SymmetricSecurityKey(key)
};
}
private bool ValidateToken(string authToken, byte[] key)
{
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = GetValidationParameters(key);
// This will raise an exception if the security token is invalid
try
{
tokenHandler.ValidateToken(authToken, validationParameters, out SecurityToken validatedToken);
}
catch (SecurityTokenException e) // this will happen if the token is properly formated but invalid (signature, validity)
{
logger.LogInformation("Invalid token received: {1}", e.Message);
return false;
}
return true;
}
Ошибка при вызове tokenHandler.ValidateToken
.Код проверки истечения срока действия токена никогда не вызывается.
образец токенов
Из приложения C # (проходит проверку):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NjM2MDQ1My1CMDJCLUU5MTEtODM5Qy1BMEE4Q0QzQUNCRjgiLCJuYmYiOjE1NTg2MTMzOTQsImV4cCI6MTU1ODYxMzY5NCwiaWF0IjoxNTU4NjEzMzk0fQ.nso4xnllNc-rXfn5riOWv5fZjNeJMgoQbyXeOltDYb0
Из моего Delphiприложение (не удается):
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2NjM2MDQ1My1CMDJCLUU5MTEtODM5Qy1BMEE4Q0QzQUNCRjgiLCJpYXQiOjE1NTg2MTYxNTgsIm5iZiI6MTU1ODYxNjE1OCwiZXhwIjoxNTU4NjE2NDU4fQ.vB_gotDk1JGiiDWPT0t6TR471Av4r-LXSgc3zab7EaU
Сообщаемая ошибка:
IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey , KeyId:
'.
Exceptions caught:
''.
token: '{"typ":"JWT","alg":"HS256"}.{"sub":"66360453-B02B-E911-839C-A0A8CD3ACBF8","iat":1558616158,"nbf":1558616158,"exp":1558616458}'.
Оба токена защищены одним и тем же общим секретным кодом (закодированным b64):
NdFCOQReqUk0mxTqI7psd9JrVjgE7bdPVfjILEa4dzE=
(Все эти данные взяты из локального тестового приложения, так что ни один секрет не пострадал при создании этого вопроса)