401 — запрос без учётных данных или с недействительными (просроченный токен). Сервер говорит: «я не знаю, кто вы». В ответе — WWW-Authenticate со схемой (Bearer). Клиент обновляет токен или отправляет пользователя на вход.
403 — пользователь известен, но действие ему запрещено: обычный пользователь открывает /admin. Повторный вход не поможет.
404 — ресурса по этому адресу нет.
Чужие ресурсы. GET /orders/1002 от пользователя, которому заказ не принадлежит. Ответ 403 подтверждает, что заказ существует, — утечка информации (перебором можно узнать число заказов, существование аккаунтов). Поэтому для ресурсов, которые не должны быть видны, отвечают 404, как будто их нет. Так делает GitHub для приватных репозиториев.
В Spring Security: неаутентифицированный запрос — AuthenticationEntryPoint → 401 (или редирект на форму входа); нет прав — AccessDeniedHandler → 403. Проверку владения удобно делать выборкой findByIdAndOwnerId — для чужого заказа она ничего не находит, и естественно получается 404.
Смежные коды: 400 — неверный запрос, 409 — конфликт состояния, 422 — бизнес-валидация, 429 — превышен лимит.