403 Forbidden vs 401 Unauthorized HTTP响应

问题描述 投票:2332回答:14

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

http-headers http-status-code-403 http-status-codes http-status-code-401 http-response-codes
14个回答
3573
投票

来自Daniel Irvine的明确解释:

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

这是您的Web服务器通常返回的响应,而不是您的Web应用程序。

这也是非常暂时的;服务器要求您再试一次。

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

收到403响应是服务器告诉你,“对不起。我知道你是谁 - 我相信你说的是谁 - 但你只是没有权限访问这个资源。也许如果您很好地询问系统管理员,您将获得许可。但是,在你的困境发生变化之前,请不要再打扰我了。“

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

关于如何使用http状态代码的另一个nice pictorial format

enter image description here


9
投票

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

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

  1. 如果他们根本没有登录,您应该返回401 Unauthorized
  2. 如果他们已登录但不属于正确的用户组,则应返回403 Forbidden

根据收到的回复评论RFC:

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

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

如果您未经身份验证,则401是正确的答案。但是,如果您未经授权,从语义上讲,403是正确的响应。


3
投票

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

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

  • 资源需要身份验证,但未指定凭据。

401:客户端应指定凭据。

  • 指定的凭据格式无效。

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

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

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

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

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

  • 指定的凭据已过期。

401:这通常与通常具有无效凭证相同,因此客户端应指定有效凭证。

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

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

  • 无论凭据如何,都无法访问特定资源。

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

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

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


2
投票

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

401:你需要HTTP basic auth才能看到这个。

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

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

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

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

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

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


1
投票

401:我不知道你是谁。这是一个验证错误。 403:我知道你是谁。但您无权访问此资源。这是授权错误。


0
投票

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

  • 401是unauthenticated(“缺乏有效的身份验证”);即'我不知道你是谁,或者我不相信你就是你说的那个人。'

401未经授权

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

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

  • 403代表unauthorized(“拒绝授权”);即'我知道你是谁,但你没有权限访问这个资源。'

403禁止

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

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

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


-4
投票

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

滚动自己的登录问题(应用程序)似乎存在问题。

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

“我听到你了,它就在这里,但试试这个(你不能看到它)”


369
投票

RFC2616

401未经授权:

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

403禁止:

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

更新

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


编辑:RFC2616已过时,请参阅RFC7231RFC7235


283
投票

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

Brief and Terse

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

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

Detailed and In-Depth

来自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


111
投票
   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),表示请求需要身份验证,通常这意味着用户需要登录(会话)。用户/代理未知的服务器。可以重复其他凭据。注意:这很令人困惑,因为它应该被命名为“未经身份验证”而不是“未经授权”。如果会话过期,这也可能在登录后发生。特例:可以代替404使用,以避免泄露资源的存在或不存在(信用@gingerCodeNinja)

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

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


108
投票

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

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

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


43
投票

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

当禁止向所有人访问资源或限制到给定网络或仅允许通过SSL访问资源时,使用403 Forbidden,只要它与HTTP身份验证无关。

如果未使用HTTP身份验证且服务是基于cookie的身份验证方案,那么现在应该返回403或404。

关于401,这是来自RFC 7235(超文本传输​​协议(HTTP / 1.1):身份验证):

3.1。 401未经授权

401(未授权)状态代码表示尚未应用请求,因为它缺少目标资源的有效身份验证凭据。源服务器必须发送WWW-Authenticate头字段(第4.4节),其中包含至少一个适用于目标资源的质询。如果请求包含身份验证凭据,则401响应表示已拒绝授权这些凭据。客户端可以使用新的或替换的Authorization头字段重复请求(第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身份验证当今的Web应用程序使用例如表单和cookie构建自定义身份验证方案。


26
投票

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

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


21
投票

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

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

它反映了许多流行的Web服务器和框架所采用的身份验证和授权方案中发生的情况。

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

6.5.3。 403禁止

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

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

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

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


11
投票

TL;DR

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

Practical Examples

如果apache需要身份验证(通过.htaccess),并且你点击Cancel,它将响应401 Authorization Required

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

RFC (2616 Section 10)

401 Unauthorized (10.4.2)

含义1:需要进行身份验证

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

含义2:认证不足

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

403 Forbidden (10.4.4)

含义:与身份验证无关

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

更多细节:

  • 服务器理解请求,但拒绝履行请求。
  • 它应该描述实体拒绝的原因
  • 可以使用状态代码404(未找到) (如果服务器想要从客户端保留此信息)
© www.soinside.com 2019 - 2024. All rights reserved.