403 Запрещено против 401 Несанкционированных HTTP-ответов
Для веб-страницы, которая существует, но для которой пользователь, который не имеет достаточных привилегий (они не вошли в систему или не принадлежат к соответствующей группе пользователей), какой надлежащий HTTP-ответ должен обслуживать? 401? 403? Что-то другое? То, что я прочитал о каждом из них до сих пор, не очень ясно о разнице между ними. Какие варианты использования подходят для каждого ответа?
22 ответа
Четкое объяснение от Даниэля Ирвина:
Проблема с 401 Unauthorized, кодом состояния HTTP для ошибок аутентификации. И это все: для аутентификации, а не для авторизации. Получив ответ 401, сервер скажет вам: "вы не аутентифицированы - либо не аутентифицированы вообще, либо аутентифицированы неправильно - но, пожалуйста, повторите аутентификацию и попробуйте снова". Чтобы выручить вас, он всегда будет включать заголовок WWW-Authenticate, который описывает как аутентифицировать.
Этот ответ обычно возвращается вашим веб-сервером, а не вашим веб-приложением.
Это также что-то очень временное; сервер просит вас попробовать еще раз.
Итак, для авторизации я использую 403 Запрещенный ответ. Это постоянно, это связано с логикой моего приложения, и это более конкретный ответ, чем 401.
При получении ответа 403 сервер говорит вам: "Извините. Я знаю, кто вы, я верю, кем вы говорите, но у вас просто нет разрешения на доступ к этому ресурсу. Может быть, если вы спросите системного администратора, вы получите разрешение. Но, пожалуйста, не беспокойте меня снова, пока ваше затруднительное положение не изменится.
Таким образом, 401 Несанкционированный ответ должен использоваться для отсутствующей или плохой аутентификации, и 403 Запрещенный ответ должен использоваться впоследствии, когда пользователь аутентифицирован, но не авторизован для выполнения запрошенной операции с данным ресурсом.
Еще один приятный графический формат использования кодов http-статуса.
См. RFC2616:
401 Несанкционированный:
Если в запрос уже включены учетные данные авторизации, то ответ 401 указывает, что в авторизации было отказано для этих учетных данных.
403 Запрещено:
Сервер понял запрос, но отказывается его выполнить.
Обновить
Из вашего варианта использования видно, что пользователь не аутентифицирован. Я бы вернул 401.
Чего не хватает другим ответам, так это того, что следует понимать, что Аутентификация и авторизация в контексте RFC 2616 относятся ТОЛЬКО к протоколу HTTP-аутентификации RFC 2617. Аутентификация по схемам вне RFC2617 не поддерживается в кодах состояния HTTP и не рассматривается при принятии решения использовать 401 или 403..
Краткое и краткое
Unauthorized указывает, что клиент не прошел проверку подлинности RFC2617, и сервер инициирует процесс проверки подлинности. Запрещено указывает, что клиент аутентифицирован по RFC2617 и не имеет авторизации, или что сервер не поддерживает RFC2617 для запрошенного ресурса.
Это означает, что если у вас есть свой собственный процесс входа в систему "по-отдельности" и вы никогда не используете HTTP-аутентификацию, 403 всегда является правильным ответом, а 401 никогда не должен использоваться.
Подробный и углубленный
От RFC2616
10.4.2 401 Несанкционированный
Запрос требует аутентификации пользователя. Ответ ДОЛЖЕН включать поле заголовка WWW-Authenticate (раздел 14.47), содержащее запрос, применимый к запрашиваемому ресурсу. Клиент МОЖЕТ повторить запрос с подходящим полем заголовка Авторизация (раздел 14.8).
а также
10.4.4 403 Запрещено Сервер понял запрос, но отказывается его выполнить. Авторизация не поможет и запрос НЕ ДОЛЖЕН повторяться.
Первое, что нужно иметь в виду, это то, что "Аутентификация" и "Авторизация" в контексте этого документа относятся конкретно к протоколам HTTP-аутентификации из RFC 2617. Они не относятся к любым протоколам аутентификации, которые вы, возможно, создали. использование страниц входа и т. д. Я буду использовать "логин" для ссылки на аутентификацию и авторизацию, отличные от RFC2617
Таким образом, реальная разница не в том, в чем проблема, или даже в том, если есть решение. Разница в том, что сервер ожидает, что клиент будет делать дальше.
401 указывает, что ресурс не может быть предоставлен, но сервер ЗАПРОСИЛ, чтобы клиент вошел через HTTP-аутентификацию и послал заголовки ответа, чтобы инициировать процесс. Возможно, есть авторизации, которые разрешат доступ к ресурсу, возможно, нет, но давайте попробуем и посмотрим, что произойдет.
403 указывает, что ресурс не может быть предоставлен, и для текущего пользователя нет никакого способа решить это через RFC2617 и нет смысла пытаться. Это может быть связано с тем, что известно, что никакого уровня аутентификации недостаточно (например, из-за черного списка IP-адресов), но это может быть связано с тем, что пользователь уже аутентифицирован и не имеет полномочий. Модель RFC2617 является однопользовательской, однопользовательской, поэтому случай, когда у пользователя может быть второй набор учетных данных, которые могут быть авторизованы, может быть проигнорирован. Это не предполагает и не подразумевает, что какая-либо страница входа в систему или другой протокол аутентификации, отличный от RFC2617, может или не может помочь - что находится за пределами стандартов и определений RFC2616.
ПОЛУЧИТЬ, ресурс существует? | | НЕТ | | ДА ст 404 Аутентифицирован ли (авторизован)? | | НЕТ | | ДА ст 401 Может ли доступ к ресурсу (имеет разрешения)? (или: 404) | | или 301 НЕТ | | ДА перенаправить В.В. для входа 403 OK 200, 301, ...
Проверки обычно проводятся в следующем порядке:
- 401, если не вошел в систему или сеанс истек
- 403, если у пользователя нет прав доступа к ресурсу
- 404 если ресурс не существует
НЕСАНКЦИОНИРОВАННО: Код состояния (401), указывающий, что запрос требует аутентификации, обычно это означает, что пользователь должен войти в систему (сеанс). Пользователь / агент неизвестен серверу. Можно повторить с другими учетными данными. ПРИМЕЧАНИЕ: это сбивает с толку, так как это должно было быть названо "неаутентифицированным" вместо "неавторизованным". Это также может произойти сбой после входа в систему, если сеанс истек.
ЗАПРЕЩЕНО: код состояния (403), указывающий, что сервер понял запрос, но отказался его выполнить. Пользователь / агент, известный серверу, но с недостаточными учетными данными. Повторный запрос не будет работать, если учетные данные не изменены, что очень маловероятно за короткий промежуток времени.
НЕ НАЙДЕН: Код состояния (404), указывающий, что запрошенный ресурс недоступен. Пользователь / агент известен, но сервер ничего не раскрывает о ресурсе, если он не существует. Повтор не сработает. Это специальное использование 404 (например, github).
Согласно RFC 2616 (HTTP / 1.1) 403 отправляется, когда:
Сервер понял запрос, но отказывается его выполнить. Авторизация не поможет и запрос НЕ ДОЛЖЕН повторяться. Если метод запроса не был HEAD и сервер желает обнародовать, почему запрос не был выполнен, он ДОЛЖЕН описать причину отказа в объекте. Если сервер не желает предоставлять эту информацию клиенту, вместо него можно использовать код состояния 404 (не найден).
Другими словами, если клиент МОЖЕТ получить доступ к ресурсу путем аутентификации, следует отправить 401.
Если аутентификация другого пользователя предоставит доступ к запрошенному ресурсу, тогда следует вернуть 401 Unauthorized. 403 Запрещено в основном используется, когда доступ к ресурсу запрещен для всех или ограничен определенной сетью или разрешен только через SSL, независимо от того, что это не связано с аутентификацией.
Из RFC 7235 (протокол передачи гипертекста (HTTP/1.1): аутентификация):
3.1. 401 Несанкционированный
Код состояния 401 (неавторизованный) указывает, что запрос не был применен, поскольку в нем отсутствуют действительные учетные данные аутентификации для целевого ресурса. Исходный сервер ДОЛЖЕН отправить поле заголовка WWW-Authenticate (раздел 4.4), содержащее как минимум один запрос, применимый к целевому ресурсу. Если в запрос включены учетные данные для проверки подлинности, то ответ 401 указывает, что для этих учетных данных было отказано в авторизации. Клиент МОЖЕТ повторить запрос с новым или замененным полем заголовка Авторизация (Раздел 4.1). Если ответ 401 содержит ту же проблему, что и предыдущий ответ, и пользовательский агент уже предпринял попытку аутентификации, по меньшей мере, один раз, то пользовательский агент ДОЛЖЕН представить приложенное представление пользователю, поскольку он обычно содержит соответствующую диагностическую информацию.
И это из RFC 2616:
10.4.4 403 Запрещено
Сервер понял запрос, но отказывается его выполнить.
Авторизация не поможет и запрос НЕ ДОЛЖЕН повторяться.
Если метод запроса не был HEAD и сервер хочет сделать
Публичный, почему запрос не был выполнен, ДОЛЖЕН описать причину отказа в организации. Если сервер не желает предоставлять эту информацию клиенту, код состояния 404
(Не найдено) можно использовать вместо.
Изменить: RFC 7231 (протокол передачи гипертекста (HTTP/1.1): семантика и контент) изменяет значение 403:
6.5.3. 403 Запрещено
Код состояния 403 (Запрещено) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть).
Если в запросе были указаны идентификационные данные,
Сервер считает их недостаточными для предоставления доступа. Клиент
НЕ ДОЛЖЕН автоматически повторять запрос с тем же
полномочия. Клиент МОЖЕТ повторить запрос с новыми или другими учетными данными. Тем не менее, запрос может быть запрещен по причинам
не связанные с полномочиями.Исходный сервер, который хочет "скрыть" текущее существование
запрещенный целевой ресурс МОЖЕТ вместо этого ответить кодом состояния
404 Не Найдено).
Таким образом, 403 теперь может означать что угодно. Предоставление новых учетных данных может помочь... или не поможет.
- 401 Неавторизованный: я не знаю, кто вы. Это ошибка аутентификации.
- 403 Запрещено: я знаю, кто вы, но у вас нет разрешения на доступ к этому ресурсу. Это ошибка авторизации.
Это более старый вопрос, но один вариант, который так и не был предложен, - вернуть 404. С точки зрения безопасности ответ, получивший наибольшее количество голосов, страдает от потенциальной уязвимости, связанной с утечкой информации. Скажем, например, что рассматриваемая защищенная веб-страница является страницей системного администратора или, что более часто, является записью в системе, к которой у пользователя нет доступа. В идеале вы бы не хотели, чтобы злоумышленник даже знал, что там есть страница / запись, не говоря уже о том, что у него нет доступа. Когда я создаю что-то вроде этого, я попытаюсь записать неавторизованные / неавторизованные запросы во внутренний журнал, но верну 404.
OWASP содержит дополнительную информацию о том, как злоумышленник может использовать этот тип информации как часть атаки.
Этот вопрос был задан некоторое время назад, но мышление людей движется дальше.
Раздел 6.5.3 в этом проекте (автор Fielding и Reschke) дает код состояния 403, немного отличающийся от того, который задокументирован в RFC 2616.
Он отражает то, что происходит в схемах аутентификации и авторизации, используемых рядом популярных веб-серверов и сред.
Я подчеркнул то, что считаю наиболее важным.
6.5.3. 403 Запрещено
Код состояния 403 (Запрещено) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть).
Если в запросе были указаны учетные данные для проверки подлинности, сервер считает их недостаточными для предоставления доступа. Клиент НЕ ДОЛЖЕН повторять запрос с теми же учетными данными. Клиент МОЖЕТ повторить запрос с новыми или другими учетными данными. Однако запрос может быть запрещен по причинам, не связанным с учетными данными.
Исходный сервер, который хочет "скрыть" текущее существование запрещенного целевого ресурса, МОЖЕТ вместо этого ответить кодом состояния 404 (Не найдено).
Какое бы соглашение вы не использовали, важно обеспечить единообразие на вашем сайте / API.
Это значения:
401: Пользователь не (правильно) аутентифицирован, ресурс / страница требует аутентификации
403: Пользователь аутентифицирован, но его роль или разрешения не позволяют получить доступ к запрошенному ресурсу, например, пользователь не является администратором, а запрошенная страница предназначена для администраторов.
TL; DR
- 401: отказ, связанный с аутентификацией
- 403: отказ, который не имеет ничего общего с аутентификацией
Практические примеры
Если Apache требует аутентификации (через .htaccess
), и вы ударили Cancel
, он ответит 401 Authorization Required
Если nginx находит файл, но не имеет прав доступа (пользователь / группа) для чтения / доступа к нему, он ответит 403 Forbidden
RFC (2616 Раздел 10)
401 Несанкционированный (10.4.2)
Значение 1: необходимо подтвердить подлинность
Запрос требует аутентификации пользователя....
Значение 2: аутентификация недостаточна
... Если в запрос уже включены учетные данные авторизации, то ответ 401 указывает, что для этих учетных данных было отказано в авторизации....
403 Запрещено (10.4.4)
Значение: не относится к аутентификации
... авторизация не поможет...
Больше деталей:
Сервер понял запрос, но отказывается его выполнить.
СЛЕДУЕТ описать причину отказа в организации
Вместо этого можно использовать код состояния 404 (не найден)
(Если сервер хочет сохранить эту информацию от клиента)
они не вошли или не принадлежат к соответствующей группе пользователей
Вы изложили два разных случая; у каждого случая должен быть свой ответ:
- Если они вообще не вошли в систему, вы должны вернуть 401 Unauthorized
- Если они вошли в систему, но не принадлежат к соответствующей группе пользователей, вы должны вернуть 403 Запрещено
Примечание к RFC на основе комментариев, полученных к этому ответу:
Если пользователь не вошел в систему, он не прошел проверку подлинности, HTTP-эквивалент которого равен 401, и в RFC он вводит в заблуждение, что называется Unauthorized. Как указано в разделе 10.4.2 для 401 Unauthorized:
"Запрос требует аутентификации пользователя".
Если вы не прошли проверку подлинности, 401 является правильным ответом. Однако, если вы не авторизованы, в семантически правильном смысле 403 - это правильный ответ.
По-английски:
401
Вам потенциально разрешен доступ, но по какой-то причине вам было отказано в этом запросе. Например, неверный пароль? Повторите попытку, вместо этого при правильном запросе вы получите успешный ответ.
403
Вам никогда не позволят. Вашего имени нет в списке, вы никогда не войдете, уйдете, не отправляйте запрос на повторную попытку, он всегда будет отклонен. Уходи.
401: Кто ты снова?? (программист заходит в бар без удостоверения личности или с неверным удостоверением личности)
403: О, отлично, снова ты. Я положил на тебя глаз. Давай, убирайся отсюда. (программист заходит в бар, из которого он вышел)
Это проще в моей голове, чем где-либо здесь, поэтому:
401: вам нужна базовая аутентификация HTTP, чтобы увидеть это.
403: Вы не можете видеть это, и базовая аутентификация HTTP не поможет.
Если пользователю просто необходимо войти в систему, используя стандартную HTML-форму входа в систему на вашем сайте, 401 не подойдет, потому что она специфична для базовой аутентификации HTTP.
Я не рекомендую использовать 403, чтобы запретить доступ к таким вещам, как /includes
Потому что, что касается Интернета, эти ресурсы вообще не существуют и поэтому должны 404.
Это оставляет 403 как "Вы должны быть авторизованы".
Другими словами, 403 означает "этот ресурс требует некоторой формы аутентификации, отличной от базовой аутентификации HTTP".
401
ответ означает одно из следующего:
- Токен доступа отсутствует.
- Маркер доступа просрочен, отозван, имеет неправильный формат или недействителен.
403
ответ, с другой стороны, означает, что токен доступа действительно действителен, но у пользователя нет соответствующих привилегий для выполнения запрошенного действия.
Я думаю, что важно учитывать, что для браузера 401 инициирует диалог аутентификации для пользователя, чтобы ввести новые учетные данные, а 403 - нет. Браузеры считают, что если возвращается 401, то пользователь должен повторно пройти аутентификацию. Таким образом, 401 означает недопустимую аутентификацию, а 403 - отсутствие разрешения.
Вот некоторые случаи в соответствии с этой логикой, когда ошибка будет возвращена из аутентификации или авторизации, с выделением важных фраз.
- Ресурс требует аутентификации, но учетные данные не указаны.
401: клиент должен указать учетные данные.
- Указанные учетные данные имеют недопустимый формат.
400: это ни 401, ни 403, поскольку синтаксические ошибки всегда должны возвращать 400.
- Указанные учетные данные ссылаются на пользователя, который не существует.
401: клиент должен указать действительные учетные данные.
- Указанные учетные данные недействительны, но указывают действительного пользователя (или не указывайте пользователя, поскольку указанный пользователь не требуется).
401: Опять же, клиент должен указать действительные учетные данные.
- Срок действия указанных учетных данных истек.
401: Это практически то же самое, что и неверные учетные данные в целом, поэтому клиент должен указать действительные учетные данные.
- Указанные учетные данные полностью действительны, но их недостаточно для конкретного ресурса, хотя вполне возможно, что учетные данные с более широкими правами могут.
403. Указание допустимых учетных данных не предоставит доступ к ресурсу, поскольку текущие учетные данные уже действительны, но только не имеют разрешения.
- Определенный ресурс недоступен независимо от учетных данных.
403. Это не зависит от учетных данных, поэтому указание действительных учетных данных не может помочь.
- Указанные учетные данные полностью действительны, но конкретный клиент заблокирован от их использования.
403. Если клиент заблокирован, указание новых учетных данных ничего не изменит.
У меня немного другой взгляд на это из принятого ответа.
Кажется более семантичным и логичным возвращать 403 при сбое аутентификации и 401 при сбое авторизации.
Вот мое обоснование этого:
Когда вы запрашиваете аутентификацию, вы имеете право сделать этот запрос. Вам нужно, иначе никто даже не сможет пройти аутентификацию.
Если ваша аутентификация не удалась, вы запрещены, это имеет семантический смысл.
С другой стороны, запрещенный может также подать заявку на авторизацию, но скажем, вы аутентифицированы и не авторизованы для доступа к определенной конечной точке. Кажется более семантичным вернуть 401 Unauthorized.
Безопасность Spring Boot возвращает 403 для неудачной попытки аутентификации
Учитывая последние RFC по этому вопросу ( 7231 и 7235), сценарий использования выглядит вполне ясным (курсив добавлен):
- 401 для неаутентифицированных ("не хватает действительной аутентификации"); то есть "я не знаю, кто вы, или я не верю, что вы тот, кем вы говорите".
401 Несанкционированный
Код состояния 401 (неавторизованный) указывает, что запрос не был применен, поскольку в нем отсутствуют действительные учетные данные аутентификации для целевого ресурса. Сервер, генерирующий ответ 401, ДОЛЖЕН отправить поле заголовка WWW-Authenticate (раздел 4.1), содержащее, по крайней мере, один запрос, применимый к целевому ресурсу.
Если в запрос включены учетные данные для проверки подлинности, то ответ 401 указывает, что для этих учетных данных было отказано в авторизации. Пользовательский агент МОЖЕТ повторить запрос с новым или замененным полем заголовка Авторизация (Раздел 4.2). Если ответ 401 содержит ту же проблему, что и предыдущий ответ, и пользовательский агент уже предпринял попытку аутентификации, по меньшей мере, один раз, то пользовательский агент ДОЛЖЕН представить приложенное представление пользователю, поскольку он обычно содержит соответствующую диагностическую информацию.
- 403 для неавторизованных ("отказывает в авторизации"); т.е. "Я знаю, кто вы, но у вас нет разрешения на доступ к этому ресурсу".
403 Запрещено
Код состояния 403 (Запрещено) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть).
Если в запросе были указаны учетные данные для проверки подлинности, сервер считает их недостаточными для предоставления доступа. Клиент НЕ ДОЛЖЕН автоматически повторять запрос с теми же учетными данными. Клиент МОЖЕТ повторить запрос с новыми или другими учетными данными. Однако запрос может быть запрещен по причинам, не связанным с учетными данными.
Исходный сервер, который хочет "скрыть" текущее существование запрещенного целевого ресурса, МОЖЕТ вместо этого ответить кодом состояния 404 (Не найдено).
Я думаю проще так:
401, если используемые вами учетные данные не распознаются системой, например, если это другая область или что-то в этом роде.
если тебе удалось пройти 401
403, если вам не разрешен доступ к ресурсу, если вы получаете это, когда вы не прошли аутентификацию, скорее всего, вы не получите его, даже если вы прошли аутентификацию, система не проверяет, есть ли у вас учетные данные или нет.
Раскрытие информации: я не читал RFC.
В случае 401 против 403, на это много раз отвечали. По сути, это дебаты "среды HTTP-запросов", а не "приложений".
Похоже, что возникает вопрос о проблеме "подкатить свой собственный логин" (приложение).
В этом случае просто не войти в систему недостаточно для отправки 401 или 403, если только вы не используете HTTP Auth против страницы входа (не привязанной к настройке HTTP Auth). Похоже, вы ищете "201 Created", с присутствующим на экране скрининга входа (вместо запрошенного ресурса) для доступа к файлу на уровне приложения. Это говорит:
"Я слышал, ты здесь, но попробуй вместо этого (тебе не разрешено это видеть)"