Ответ
Согласно спецификации RFC 6750 (Bearer Token Usage) и общепринятой практике, для просроченного (или недействительного) токена должен возвращаться статус 401 Unauthorized.
Почему именно 401, а не 403?
401 Unauthorizedозначает, что запрос не содержит корректных учетных данных для аутентификации. Сервер "не знает", кто вы. Просроченный токен — это некорректные учетные данные.403 Forbiddenозначает, что сервер понял, кто вы (аутентификация успешна), но у вас недостаточно прав для доступа к ресурсу. Это другая ситуация.
Правильная реализация в ASP.NET Core:
-
В обработчике аутентификации (например, JWT Bearer): При проверке токена, если он просрочен, схема аутентификации автоматически завершится с ошибкой, и фреймворк вернет
401. -
Для явного возврата с дополнительной информацией (в контроллере или middleware):
[Authorize] public class SecureController : ControllerBase { [HttpGet("data")] public IActionResult GetData() { // Проверка, выполненная кастомной логикой if (HttpContext.User.IsTokenExpired()) { // Рекомендуется также добавить заголовок WWW-Authenticate Response.Headers.WWWAuthenticate = "Bearer error="invalid_token", error_description="The access token expired""; return Unauthorized(new { error = "invalid_token", message = "Token has expired" }); } return Ok("Sensitive data"); } } -
Использование
[Authorize]с политиками: Можно создать политику, которая проверяет не только наличие, но и валидность/срок токена.services.AddAuthorization(options => { options.AddPolicy("ValidToken", policy => policy.RequireAssertion(context => context.User.Identity?.IsAuthenticated == true && !context.User.IsTokenExpired())); });Затем использовать
[Authorize(Policy = "ValidToken")]. При неудаче политики также вернется401.
Ключевой вывод: Всегда используйте 401 Unauthorized для проблем с аутентификацией (неверный/просроченный/отозванный токен). Используйте 403 Forbidden только когда пользователь аутентифицирован, но его роли или claims не позволяют выполнить действие.