#.net-core #jwt #.net-5
Вопрос:
Я пытаюсь реализовать аутентификацию JWT в веб-интерфейсе .NET 5. Все работает нормально, пока я не добавлю в приложение дополнительные веб-серверы. Как я мог бы хранить JWT, например, в базе данных SQL Server вместо того, чтобы хранить их в памяти на одном сервере?
Вот реализация, работающая на одном сервере:
Запуск
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Context.JwtIssuer,
ValidAudience = Context.JwtIssuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Context.JwtSecretKey))
};
}
Контроллер
[HttpGet("Login")]
public IActionResult Login(string uid, string password)
{
var hash = _userManager.GetPasswordHash(uid);
if (string.IsNullOrEmpty(hash))
{
return NotFound("Account not found");
}
if (!_passwordHasher.Check(hash, password))
{
return Unauthorized("Uid/password not correct");
}
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Context.JwtSecretKey));
var token = new JwtSecurityToken(
issuer: Context.JwtIssuer,
audience: Context.JwtIssuer,
expires: DateTime.Now.AddHours(3),
claims: new List<Claim>() { new Claim(ClaimTypes.Name, uid)},
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
Комментарии:
1. какая именно проблема у вас с большим количеством веб-серверов и для какой цели вам нужно хранить JWT в памяти или в базе данных?
2. Если я войду в WebAPI и, таким образом, создам Токен на стороне сервера, но при следующем вызове попаду на другой веб-сервер, токен там будет недействителен. Верно?
3. токен проверяется его подписью плюс полезной нагрузкой (время истечения срока действия, роль, аудитория), нет необходимости хранить его на стороне сервера. Обычно у вас есть один сервер авторизации (выдающий токен) и несколько серверов ресурсов. Серверы ресурсов имеют доступ к одному и тому же открытому ключу, соответствующему закрытому ключу, с помощью которого был подписан токен.
4. О, замечательно, я не знала! Я постараюсь в ближайшее время
5. Он имеет в виду, что это
options.SaveToken
не должно быть правдой. 🙂 Это делает его надлежащим токеном «на предъявителя» (что означает, что он действует как ключ, без необходимости существования токена на стороне сервера). Конечно, еще одним требованием является создание токенов с одним и тем же ключом шифрования, по крайней мере, в разных экземплярах (но в сценариях с несколькими экземплярами лучше использовать централизованный орган, да).