403 Forbidden vs 401 Unauthorized HTTP响应

时间:2010-07-21 07:21:58

标签: http-headers http-status-code-403 http-status-codes http-status-code-401 http-response-codes

对于存在的网页,但对于没有足够权限的用户(他们未登录或不属于正确的用户组),要提供的正确HTTP响应是什么? 401? 403?别的什么?到目前为止,我对每个人的看法都不太清楚。哪些用例适合每个响应?

17 个答案:

答案 0 :(得分:3415)

来自Daniel Irvine的明确解释:

  

401 Unauthorized 存在问题,这是用于身份验证错误的HTTP状态代码。就是这样:它是用于身份验证,而不是授权。   收到401响应是服务器告诉你,“你不是   经过身份验证 - 未经过身份验证或经过身份验证   不正确 - 但请重新认证,然后再试一次。“为了帮助你,   它将始终包含描述方式的 WWW-Authenticate 标头   进行身份验证。

     

这是您的网络服务器通常返回的响应,而不是您的网络   应用

     

这也是非常暂时的;服务器要求你试试   试。

     

因此,对于授权,我使用 403 Forbidden 响应。它的   永久性,它与我的应用程序逻辑紧密相关,而且更具体   回应比401。

     

收到403响应是服务器告诉你,“对不起。我知道   你是谁 - 我相信你说的是谁 - 但你没有   访问此资源的权限。也许你问问系统   管理员很好,你会获得许可。但请不要打扰   再次,直到你的困境发生变化。“

     

总之, 401 Unauthorized 响应应该用于丢失   或错误的身份验证,应使用 403 Forbidden 响应   之后,当用户通过身份验证但未获得授权时   对给定资源执行请求的操作。

应该使用http状态代码的另一个nice pictorial format

答案 1 :(得分:362)

请参阅RFC2616

401 Unauthorized:

  

如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据。

403 Forbidden:

  

服务器理解请求,但拒绝履行请求。

<强>更新

从您的用例中可以看出,用户未经过身份验证。我会回401。


修改:RFC2616已过时,请参阅RFC7231RFC7235

答案 2 :(得分:279)

缺少其他答案的一点是,必须理解RFC 2616上下文中的身份验证和授权仅涉及RFC 2617的HTTP身份验证协议.HTTP状态代码中不支持RFC2617以外的方案的身份验证在决定是否使用401或403时不予考虑。

简要和Terse

未授权表示客户端未通过RFC2617身份验证,并且服务器正在启动身份验证过程。 Forbidden表示客户端已通过RFC2617身份验证且没有授权,或者服务器不支持所请求资源的RFC2617。

这意味着如果您拥有自己的滚动登录过程并且从不使用HTTP身份验证,则403始终是正确的响应,并且永远不应使用401。

详细和深入

来自RFC2616

  

10.4.2 401未经授权

     

请求需要用户身份验证。响应必须包含WWW-Authenticate头字段(第14.47节),其中包含适用于所请求资源的质询。客户端可以使用合适的Authorization头字段重复请求(第14.8节)。

  

10.4.4 403禁止   服务器理解请求但拒绝履行请求。授权无效,请求不应重复。

首先要记住的是,本文档上下文中的“身份验证”和“授权”特指RFC 2617中的HTTP身份验证协议。它们不是指您自己的任何身份验证协议可能是使用登录页面等创建的。我将使用“登录”来指代RFC2617以外的方法进行身份验证和授权

所以真正的区别不在于问题是什么,甚至是否有解决方案。不同之处在于服务器期望客户端下一步做什么。

401表示无法提供资源,但服务器要求客户端通过HTTP身份验证登录并发送了回复标头以启动该过程。可能有允许访问资源的授权,可能没有,但让我们试一试,看看会发生什么。

403表示无法提供资源,并且对于当前用户而言,无法通过RFC2617解决此问题,并且无需尝试。这可能是因为已知没有任何级别的身份验证就足够了(例如由于IP黑名单),但可能是因为用户已经过身份验证且没有权限。 RFC2617模型是单用户,一个凭证,因此可以忽略用户可能拥有可以授权的第二组凭证的情况。它既不暗示也不暗示某种登录页面或其他非RFC2617认证协议可能有所帮助 - 也可能没有帮助 - 这超出了RFC2616标准和定义。


修改:RFC2616已过时,请参阅RFC7231RFC7235

答案 3 :(得分:107)

根据RFC 2616(HTTP / 1.1)403在以下时间发送:

  

服务器理解请求,但拒绝履行请求。授权无效,请求不应重复。如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)

换句话说,如果客户端通过身份验证可以访问资源,则应该发送401。

答案 4 :(得分:103)

   Resource exists ?
    |       |
 NO |       | YES
    v       v
   404      Is logged-in (authenticated) ?
   or         |              |
   401     NO |              | YES
   403        |              |
              v              v
              401            Can access resource, permissions (authorized) ?
         (404 no reveal)      |            |
             or 301        NO |            | YES
             redirect         |            |
             to login         v            v
                              403          OK 200, 301, ...
                      (or 404: no reveal)

检查通常按以下顺序进行:

  • 401,如果没有登录或会话已过期
  • 403如果用户没有访问资源的权限(文件,json,...)
  • 404如果资源不存在(或不愿透露任何内容)

UNAUTHORIZED :状态代码(401),表示请求需要身份验证,通常这意味着用户需要登录(会话)。用户/代理未知的服务器。可以重复其他凭据。注意:这是令人困惑的,因为它应该被命名为“未经身份验证的”#39;而不是未经授权的&#39;。如果会话过期,这也可能在登录后失败。 特殊情况:可以代替404使用以避免泄露资源的存在或不存在(信用@gingerCodeNinja)

FORBIDDEN :状态代码(403),表示服务器理解了请求但拒绝履行请求。用户/代理已知服务器但凭据不足。除非凭据更改,否则重复请求将不起作用,这在短时间内不太可能发生。 特殊情况:可以代替404使用以避免泄露资源的存在或不存在(信用@gingerCodeNinja)

NOT FOUND :状态代码(404),表示请求的资源不可用。用户/代理已知,但服务器不会透露有关资源的任何信息,就好像它不存在一样。重复不起作用。这是404的特殊用法(例如github)。

答案 5 :(得分:43)

假设HTTP身份验证 WWW-Authenticate 授权标头)正在使用,如果身份验证为另一个用户将授予对所请求资源的访问权限,然后应返回401 Unauthorized。

403只要与HTTP身份验证无关,只要禁止对每个人访问资源或限制到给定网络或仅允许通过SSL访问资源,就会使用403 Forbidden。

如果未使用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(Forbidden)状态代码表示服务器   了解该请求但拒绝授权。一个服务器   希望公开为什么禁止请求可以   在响应有效载荷中描述该原因(如果有的话)。

     

如果请求中提供了身份验证凭据,则   服务器认为它们不足以授予访问权限客户
  不应该自动重复使用相同的请求   证书。客户端可以用新的或不同的方式重复请求   证书。但是,出于原因,可能会禁止请求   与凭据无关。

     

希望“隐藏”当前存在的原始服务器   禁止目标资源可以用状态代码
来响应   404(未找到)。

因此,403(或404)现在可能意味着什么。提供新凭据可能会有所帮助......或者可能没有。

我相信这已经改变的原因是RFC 2616假设在实践中将使用HTTP身份验证今天的Web应用程序使用例如表单和cookie构建自定义身份验证方案。

答案 6 :(得分:26)

这是一个较旧的问题,但从未真正提出的一个选项是返回404.从安全角度来看,最高投票的答案会受到潜在的information leakage vulnerability的影响。例如,假设所讨论的安全网页是系统管理页面,或者更常见的是,系统中的记录是用户无法访问的。理想情况下,您不希望恶意用户知道那里有一个页面/记录,更不用说他们没有访问权限了。当我构建这样的内容时,我会尝试在内部日志中记录未经身份验证/未经授权的请求,但返回404。

OWASP有一些more information关于攻击者如何将此类信息用作攻击的一部分。

答案 7 :(得分:21)

这个问题前一段时间被问过,但人们的想法仍在继续。

本草案中的

Section 6.5.3(由Fielding和Reschke撰写)给出了状态代码403与RFC 2616中记录的含义略有不同的含义。

它反映了身份验证和&amp ;;许多流行的Web服务器和框架使用的授权方案。

我强调了我认为最突出的一点。

  

<强> 6.5.3。 403禁止

     

403(禁止)状态代码表示服务器理解请求但拒绝授权。希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话)。

     

如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限。 客户端不应该使用相同的凭据重复请求。客户端可以使用新的或不同的凭据重复请求。 但是,出于与凭证无关的原因,可能会禁止请求。

     

希望“隐藏”当前存在的禁止目标资源的原始服务器可以使用状态代码404(未找到)进行响应。

无论您使用哪种惯例,重要的是在您的网站/ API中提供一致性。

答案 8 :(得分:11)

TL; DR

  • 401:拒绝与身份验证有关
  • 403:拒绝与身份验证无关

实例

如果 apache 需要身份验证(通过.htaccess),并点击Cancel,则会以401 Authorization Required <回复/ p>

如果 nginx 找到一个文件但没有访问权限(用户/组)来阅读/访问它,它将以403 Forbidden

RFC(2616第10节)

401 Unauthorized(10.4.2)

含义1:需要验证

  

请求需要用户身份验证。 ...

含义2:身份验证不足

  

...如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据。 ...

403 Forbidden(10.4.4)

含义:与身份验证无关

  

......授权无济于事......

更多详情:

  •   

    服务器理解请求,但拒绝履行请求。

  •   

    它应该描述实体拒绝的原因

  •   

    可以使用状态代码404(未找到)

    (如果服务器想要从客户端保留此信息)

答案 9 :(得分:9)

  

他们未登录或不属于正确的用户组

你说过两种不同的情况;每个案例应该有不同的回应:

  1. 如果他们根本没有登录,您应该返回 401 Unauthorized
  2. 如果他们已登录但不属于正确的用户组,则应返回 403 Forbidden
  3. 根据收到的答案注释RFC:

    如果用户未登录,则他们未经过身份验证,其HTTP等效值为401,并且在RFC中误导性地称为“未授权”。正如section 10.4.2指出 401 Unauthorized

      

    “请求需要用户身份验证。”

    如果您未经身份验证,则401是正确的回复。但是,如果你是未经授权的,从语义上来看,403是正确的反应。

答案 10 :(得分:8)

401 :我不知道你是谁。这是身份验证错误。 403 :我知道你是谁。但是您没有访问此资源的权限。这是授权错误。

答案 11 :(得分:8)

英语:

401

您可能被允许访问,但是由于某些原因,您被 否认。如密码错误?根据正确的请求重试 您将获得成功的回应。

403

永远不允许您。您的名字不在名单上,您不会 进入,离开,不发送重试请求,都会被拒绝, 总是。走开。

答案 12 :(得分:4)

这些是含义:

401 :未(正确)认证用户,资源/页面需要认证

403 :用户已通过身份验证,但其角色或权限不允许访问请求的资源,例如,用户不是管理员,而请求的页面是针对管理员的

答案 13 :(得分:3)

我认为重要的是要考虑到,对于浏览器,401启动用户输入新凭据的身份验证对话框,而403则不然。浏览器认为,如果返回401,则用户应重新进行身份验证。所以401代表无效认证,而403代表缺乏许可。

以下是该逻辑下的一些案例,其中将从身份验证或授权中返回错误,重要的短语加粗。

  • 资源需要身份验证,无凭据 指定

401 :客户端应指定凭据。

  • 指定的凭据采用格式无效

400 :既不是401也不是403,因为语法错误应该总是返回400.

  • 指定的凭据引用用户 不存在

401 :客户端应指定有效凭据。

  • 指定的凭据 无效,但指定有效用户(如果不需要指定用户,则不指定用户)。

401 :同样,客户端应指定有效的凭据。

  • 指定的凭据 已过期

401 :这与一般无效凭据几乎相同,因此客户端应指定有效凭据。

  • 指定的凭据完全有效,但不足特定的资源,但可能会有更多权限的凭据。

403 :指定有效凭据不会授予对资源的访问权限,因为当前凭据已经有效但只有权限。

  • 无论凭据如何,资源无法访问

403 :这与凭据无关,因此指定有效凭据无济于事。

  • 指定的凭据完全有效,但特定的客户 已阻止使用它们。

403 :如果客户端被阻止,指定新凭据将无法执行任何操作。

答案 14 :(得分:2)

这比我在这里的任何地方都要简单,所以:

401:您需要HTTP基本身份验证来查看此内容。

403:你看不到这一点,HTTP基本身份验证也无济于事。

如果用户只需使用您网站的标准HTML登录表单登录,则401不合适,因为它特定于HTTP基本身份验证。

我不建议使用403拒绝访问/includes之类的内容,因为就网络而言,这些资源根本不存在,因此应该是404。

这留下403为“你需要登录”。

换句话说,403表示“此资源需要除HTTP基本身份验证之外的某种形式的身份验证”。

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

答案 15 :(得分:0)

鉴于有关此问题的最新RFC(72317235),用例似乎非常清楚(斜体添加):

  • 401适用于unauthenticated(&#34;缺少有效身份验证&#34;);即“我不知道你是谁,或者我不相信你就是你说的那个人。”#39;
  

401未经授权

     

401(未授权)状态代码表示请求没有      已被应用,因为缺少有效的身份验证凭据      目标资源。生成401响应的服务器必须发送      包含至少一个的WWW-Authenticate头字段(第4.1节)      适用于目标资源的挑战。

     

如果请求包含身份验证凭据,则为401      回复表明授权已被拒绝      证书。用户代理可以用新的或重复请求      替换了Authorization标头字段(第4.2节)。如果是401      响应包含与先前响应相同的挑战,以及      用户代理已经尝试过至少一次身份验证      用户代理应该将所附的表示呈现给      用户,因为它通常包含相关的诊断信息。

  • 403适用于unauthorized(&#34;拒绝授权&#34;);即“我知道你是谁,但你没有权限访问这个资源。&#39;
  

403禁止

     

403(禁止)状态代码表示服务器已理解      请求,但拒绝授权它。希望的服务器      公开为什么禁止请求可以描述      响应有效负载中的原因(如果有的话)。

     

如果请求中提供了身份验证凭据,则      服务器认为它们不足以授予访问权限客户端      不应该自动重复请求      证书。客户端可以用新的或不同的方式重复请求      证书。但是,出于原因可能会禁止请求      与证书无关。

     

希望隐藏&#34;的原始服务器目前存在的一个      禁止目标资源可以用状态代码响应      404(未找到)。

答案 16 :(得分:-4)

在401 vs 403的情况下,这已被多次回答。这本质上是一个HTTP请求环境&#39;辩论,而不是一个应用程序&#39;辩论。

关于滚动你自己的登录问题(应用程序)似乎有一个问题。

在这种情况下,除非您使用HTTP Auth vs登录页面(不依赖于设置HTTP Auth),否则仅仅登录不足以发送401或403。听起来您可能正在寻找一个&#34; 201 Created&#34;,其中存在自己的滚动登录屏幕(而不是请求的资源),用于对文件的应用程序级访问。这说:

&#34;我听到了你,它在这里,但试试这个(你不被允许看到它)&#34;