403 Запрещено vs 401 Неавторизованные ответы HTTP

Для веб-страницы, которая существует, но для которой пользователь, который не имеет достаточных привилегий (они не вошли в систему или не принадлежат к соответствующей группе пользователей), каков правильный HTTP-ответ для обслуживания? 401? 403? Что-то другое? То, что я читал на каждом из них до сих пор, не очень ясно видно о различии между ними. Какие варианты использования подходят для каждого ответа?

Ответ 1

Четкое объяснение от Даниэля Ирвина:

Проблема с 401 Unauthorized, кодом состояния HTTP для ошибок аутентификации. И это только: аутентификация, а не авторизация. Получив ответ 401, сервер скажет вам: "Вы не аутентифицированы - либо не аутентифицированы вообще, либо аутентифицированы неправильно - но, пожалуйста, повторите аутентификацию и попробуйте снова". Чтобы помочь вам, он всегда будет включать заголовок WWW-Authenticate, который описывает, как пройти аутентификацию.

Этот ответ обычно возвращается вашим веб-сервером, а не вашим веб-приложением.

Это также что-то очень временное; сервер просит вас попробовать еще раз.

Итак, для авторизации я использую 403 Запрещенный ответ. Он постоянен, привязан к логике моего приложения и более конкретен, чем 401.

Получив ответ 403, сервер говорит вам: "Извините. Я знаю, кто вы, я верю, кем вы говорите, но у вас просто нет разрешения на доступ к этому ресурсу. Возможно, если вы спросите системного администратора, вы получите разрешение. Но, пожалуйста, не беспокойте меня снова, пока ваше затруднительное положение не изменится. "

Таким образом, 401 неавторизованный ответ должен использоваться для отсутствующей или плохой аутентификации, и 403 Запрещенный ответ должен использоваться впоследствии, когда пользователь аутентифицирован, но не авторизован для выполнения запрошенной операции с данным ресурсом.

Еще один приятный графический формат того, как следует использовать коды состояния http.

enter image description here

Ответ 2

См. RFC2616:

401 Несанкционированный:

Если запрос уже включил учетные данные авторизации, тогда ответ 401 указывает, что для этих учетных данных было отказано в авторизации.

403 Запрещено:

Сервер понял запрос, но отказывается его выполнять.

Обновление

Из вашего варианта использования выясняется, что пользователь не аутентифицирован. Я верну 401.


Изменить: RFC2616 устарел, см. RFC7231 и RFC7235.

Ответ 3

Чего не хватает другим ответам, так это того, что следует понимать, что Аутентификация и Авторизация в контексте 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.


Изменение: RFC2616 устарел, см. RFC7231 и RFC7235.

Ответ 4

   Resource exists ? (if private it is often checked AFTER auth check)
    |       |
 NO |       | YES
    v       v
   404      Is logged-in ? (authenticated, aka has session)
   or         |              |
   401     NO |              | YES
   403        |              |
              v              v
              401            Can access resource ? (permission, authorized) ?
         (404 no reveal)      |            |
             or 301        NO |            | YES
             redirect         |            |
             to login         v            v
                              403          OK 200, 301, ...
                      (or 404: no reveal)

Проверки обычно выполняются в следующем порядке:

  • 401, если не вошел в систему или сеанс истек
  • 403, если у пользователя нет прав доступа к ресурсу (file, json,...)
  • 404 если ресурс не существует (или не хочет ничего раскрывать)

UNAUTHORIZED: код состояния (401), указывающий, что для запроса требуется аутентификация, обычно это означает, что пользователь должен войти в систему (сеанс). Пользователь/агент неизвестен серверу. Можно повторить с другими учетными данными. ПРИМЕЧАНИЕ: это сбивает с толку, поскольку это должно было быть названо "неаутентифицированным" вместо "неавторизованным". Это также может произойти после входа в систему, если сеанс истек. Особый случай: может использоваться вместо 404, чтобы избежать выявления наличия или отсутствия ресурса (credits @gingerCodeNinja)

ЗАПРЕЩЕНО: код состояния (403), указывающий, что сервер понял запрос, но отказался его выполнить. Пользователь/агент известен серверу, но у него недостаточно учетных данных. Повторный запрос не будет работать, если учетные данные не изменены, что очень маловероятно за короткий промежуток времени. Особый случай: можно использовать вместо 404, чтобы избежать выявления наличия или отсутствия ресурса (credits @gingerCodeNinja)

НЕ НАЙДЕНО: код состояния (404), указывающий, что запрошенный ресурс недоступен. Пользователь/агент известен, но сервер ничего не раскрывает о ресурсе, если он не существует. Повтор не сработает. Это специальное использование 404 (например, github).

Ответ 5

В соответствии с RFC 2616 (HTTP/1.1) 403 отправляется, когда:

Сервер понял запрос, но отказывается его выполнять. Авторизация не поможет, и запрос НЕ ДОЛЖЕН повториться. Если метод запроса не был HEAD, и сервер хочет сообщить, почему запрос не был выполнен, ему ДОЛЖЕН описать причину отказа в сущности. Если сервер не желает предоставлять эту информацию клиенту, вместо этого может быть использован код состояния 404 (не найден)

Другими словами, если клиент МОЖЕТ получить доступ к ресурсу путем аутентификации, необходимо отправить 401.

Ответ 6

Предполагая, что аутентификация HTTP (WWW-аутентификации и авторизации заголовков) используется, если аутентификация как другой пользователь будет предоставлять доступ к запрашиваемому ресурсу, а затем 401 Несанкционированное должен быть возвращен.

403 Запрещено используется, когда доступ к ресурсу запрещен для всех или ограничен определенной сетью или разрешен только через SSL, независимо от того, что это не связано с HTTP-аутентификацией.

Если HTTP-аутентификация не используется и обслуживает схему аутентификации на основе файлов cookie, что является нормой в настоящее время, то должны быть возвращены 403 или 404.

Что касается 401, это из RFC 7235 (протокол передачи гипертекста (HTTP/1.1): аутентификация):

3.1. 401 Несанкционированный

Код состояния 401 (неавторизованный) указывает, что запрос не был применен, поскольку в нем отсутствуют действительные учетные данные аутентификации для целевого ресурса. Исходный сервер ДОЛЖЕН отправить поле заголовка WWW-Authenticate (раздел 4.4), содержащее как минимум один запрос, применимый к целевому ресурсу. Если в запрос включены учетные данные для проверки подлинности, то в ответе 401 указывается, что для этих учетных данных было отказано в авторизации. Клиент МОЖЕТ повторить запрос с новым или замененным полем заголовка Авторизация (Раздел 4.1). Если ответ 401 содержит ту же проблему, что и предыдущий ответ, и пользовательский агент уже предпринял попытку аутентификации, по крайней мере, один раз, тогда пользовательский агент ДОЛЖЕН представить приложенное представление пользователю, поскольку он обычно содержит соответствующую диагностическую информацию.

Семантика 403 (и 404) со временем изменилась. Это с 1999 года (RFC 2616):

10.4.4 403 Запрещено

Сервер понял запрос, но отказывается его выполнить.
Авторизация не поможет и запрос НЕ ДОЛЖЕН повторяться.
Если метод запроса не был HEAD и сервер хочет сделать
Публичный, почему запрос не был выполнен, он ДОЛЖЕН описать причину отказа в организации. Если сервер не желает предоставлять эту информацию клиенту, код состояния 404
(Не найдено) можно использовать вместо.

В 2014 RFC 7231 (протокол передачи гипертекста (HTTP/1.1): семантика и контент) изменил значение 403:

6.5.3. 403 Запрещено

Код состояния 403 (Запрещено) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который желает обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть).

Если в запросе были указаны идентификационные данные,
Сервер считает их недостаточными для предоставления доступа. Клиент
НЕ ДОЛЖЕН автоматически повторять запрос с тем же
полномочия. Клиент МОЖЕТ повторить запрос с новыми или другими учетными данными. Тем не менее, запрос может быть запрещен по причинам
не связанные с полномочиями.

Исходный сервер, который хочет "скрыть" текущее существование
запрещенный целевой ресурс МОЖЕТ вместо этого ответить кодом состояния
404 Не Найдено).

Таким образом, 403 (или 404) теперь может означать что угодно. Предоставление новых учетных данных может помочь... или не поможет.

Я полагаю, что причина, по которой это изменилось, заключается в том, что RFC 2616 предполагал, что аутентификация HTTP будет использоваться, когда на практике сегодня веб-приложения создают собственные схемы аутентификации с использованием, например, форм и файлов cookie.

Ответ 7

Это более старый вопрос, но один из вариантов, который никогда не был поднят, состоял в том, чтобы вернуть 404. С точки зрения безопасности самый высокий голосовой ответ страдает от потенциальной уязвимости утечки информации. Скажем, например, что рассматриваемая защищенная веб-страница является системной административной страницей или, что чаще всего, является записью в системе, к которой у пользователя нет доступа. В идеале вы не хотите, чтобы злонамеренный пользователь даже знал, что там есть страница/запись, не говоря уже о том, что у них нет доступа. Когда я создаю что-то вроде этого, я попытаюсь записать unauthenticate/unauthorized запросы во внутреннем журнале, но вернул 404.

OWASP имеет дополнительную информацию о том, как злоумышленник может использовать этот тип информации как часть атаки.

Ответ 8

Этот вопрос был задан некоторое время назад, но люди думают, движется дальше.

Раздел 6.5.3 в этом проекте (автор Fielding и Reschke) дает код статуса 403, несколько отличающийся от значения, описанного в RFC 2616.

Он отражает то, что происходит в схемах аутентификации и авторизации, используемых рядом популярных веб-серверов и фреймворков.

Я подчеркнул, что бит, который, по моему мнению, наиболее примечателен.

6.5.3. 403 Запрещено

Код статуса 403 (Forbidden) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть).

Если в запросе были предоставлены учетные данные, сервер считает их недостаточными для предоставления доступа. Клиент НЕ ДОЛЖЕН повторять запрос с теми же учетными данными. Клиент МОЖЕТ повторить запрос с новыми или разными учетными данными. Однако запрос может быть запрещен по причинам, не связанным с учетными данными.

Сервер происхождения, который хочет "скрыть" текущее существование запрещенного целевого ресурса, может вместо этого отвечать кодом состояния 404 (не найден).

Независимо от того, какое соглашение вы используете, важно обеспечить единообразие на вашем сайте/API.

Ответ 9

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 (не найден)

    (Если сервер хочет сохранить эту информацию от клиента)

Ответ 10

они не вошли в систему или не принадлежат к соответствующей группе пользователей

Вы заявили два разных случая; каждый случай должен иметь другой ответ:

  1. Если они вообще не вошли в систему, вы должны вернуть 401 Unauthorized
  2. Если они вошли в систему, но не принадлежат к соответствующей группе пользователей, вы должны вернуть 403 Запрещено

Примечание по RFC, основанному на комментариях, полученных к этому ответу:

Если пользователь не вошел в систему, они не аутентифицированы, HTTP-эквивалент которого равен 401 и вводится в заблуждение в качестве недопустимого в RFC. Поскольку в разделе 10.4.2 указано 401 Несанкционированное:

"Запрос требует аутентификации пользователя".

Если вы не прошли проверку, 401 - правильный ответ. Однако, если вы несанкционированный, в семантически правильном смысле, 403 - правильный ответ.

Ответ 11

401: я не знаю, кто вы. Это ошибка аутентификации. 403: я знаю, кто ты. Но у вас нет разрешения на доступ к этому ресурсу. Это ошибка авторизации.

Ответ 12

Это проще в моей голове, чем где-либо здесь, поэтому:

401: для этого вам требуется HTTP basic auth.

403: Вы не можете видеть это, и HTTP basic auth не поможет.

Если пользователю просто нужно войти в систему, используя стандартную форму входа в систему на вашем сайте, 401 не будет подходящим, поскольку он специфичен для HTTP basic auth.

Я не рекомендую использовать 403, чтобы запретить доступ к вещам типа /includes, потому что в отношении Интернета эти ресурсы вообще не существуют и поэтому должны быть 404.

Это оставляет 403 как "вам нужно войти в систему".

Другими словами, 403 означает, что "этот ресурс требует некоторую форму auth, кроме HTTP basic auth".

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2

Ответ 13

Я думаю, что важно учитывать, что для браузера 401 инициирует диалог аутентификации для пользователя, чтобы ввести новые учетные данные, а 403 - нет. Браузеры считают, что если возвращается 401, то пользователь должен повторно пройти аутентификацию. Таким образом, 401 означает недопустимую аутентификацию, а 403 - отсутствие разрешения.

Вот некоторые случаи в соответствии с этой логикой, когда ошибка будет возвращена из аутентификации или авторизации, с выделением важных фраз.

  • Ресурс требует аутентификации, но учетные данные не указаны.

401: клиент должен указать учетные данные.

  • Указанные учетные данные имеют недопустимый формат.

400: что ни 401, ни 403, поскольку синтаксические ошибки всегда должны возвращать 400.

  • Указанные учетные данные ссылаются на пользователя, который не существует.

401: клиент должен указать действительные учетные данные.

  • Указанные учетные данные недействительны, но указывают действительного пользователя (или не указывайте пользователя, если указанный пользователь не требуется).

401: Опять же, клиент должен указать действительные учетные данные.

  • Срок действия указанных учетных данных истек.

401: Это практически то же самое, что и неверные учетные данные в целом, поэтому клиент должен указать действительные учетные данные.

  • Указанные учетные данные полностью действительны, но их недостаточно для конкретного ресурса, хотя вполне возможно, что учетные данные с более широкими правами могут.

403. Указание допустимых учетных данных не предоставит доступ к ресурсу, поскольку текущие учетные данные уже действительны, но только не имеют разрешения.

  • Определенный ресурс недоступен независимо от учетных данных.

403. Это не зависит от учетных данных, поэтому указание действительных учетных данных не может помочь.

  • Указанные учетные данные полностью действительны, но конкретный клиент заблокирован от их использования.

403. Если клиент заблокирован, указание новых учетных данных ничего не изменит.

Ответ 14

Учитывая последний RFC по этому вопросу (7231 и 7235), прецедент кажется вполне понятным (курсив добавлен):

  • 401 - для не прошедших проверку подлинности ("отсутствует достоверная проверка подлинности"); т.е. "Я не знаю, кто вы, или я не верю, что вы такие, кем вы себя называете".

401 Несанкционированный

Код статуса 401 (Несанкционированный) указывает, что запрос не был применен, поскольку ему не хватает действительных учетных данных для целевого ресурса. Сервер, генерирующий ответ 401, ДОЛЖЕН отправить поле заголовка WWW-Authenticate (раздел 4.1), содержащее хотя бы одну проблему, применимую к целевому ресурсу.

Если запрос включает аутентификационные данные, то ответ 401 указывает, что для этих учетных данных было отказано в авторизации. Пользовательский агент МОЖЕТ повторить запрос с новым или замененным заголовком заголовка авторизации (раздел 4.2). Если ответ 401 содержит ту же проблему, что и предыдущий ответ, и пользовательский агент уже пытался выполнить аутентификацию хотя бы один раз, тогда пользовательский агент ДОЛЖЕН представить закрытое представление пользователю, поскольку оно обычно содержит соответствующую диагностическую информацию.

  • 403 предназначен для несанкционированных ("отказывается санкционировать"); т.е. "Я знаю, кто вы, но у вас нет разрешения на доступ к этому ресурсу".

403 Запрещено

Код статуса 403 (Forbidden) указывает, что сервер понял запрос, но отказывается его авторизовать. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если таковая имеется).

Если в запросе были предоставлены учетные данные, сервер считает их недостаточными для предоставления доступа. Клиент НЕ ДОЛЖЕН автоматически повторять запрос с теми же учетными данными. Клиент МОЖЕТ повторить запрос с новыми или разными учетными данными. Однако запрос может быть запрещен по причинам, не связанным с полномочиями.

Исходный сервер, который хочет "скрыть" текущее существование запрещенного целевого ресурса, может вместо этого отвечать кодом состояния 404 (Not Found).

Ответ 15

В случае 401 против 403 это ответили много раз. Это, по сути, дискуссия "HTTP-запрос", а не дискуссия "приложений".

Кажется, возникает вопрос о проблеме ( "приложение" ) для входа в систему.

В этом случае просто не войти в систему недостаточно для отправки 401 или 403, если вы не используете HTTP Auth и страницу входа (не привязанной к настройке HTTP Auth). Похоже, что вы можете искать "201 создан", на котором присутствует экран входа в свой собственный браузер (вместо запрашиваемого ресурса) для доступа к файлу на уровне приложения. Это говорит:

"Я слышал, вы здесь, но попробуйте это вместо этого (вам не разрешено это видеть)"