403 Forbidden vs 401 Unauthorized HTTP响应

403 Forbidden vs 401 Unauthorized HTTP responses

对于存在但用户没有足够权限(他们没有登录或不属于正确的用户组)的网页,要提供什么适当的HTTP响应?401?403?还有别的吗?到目前为止,我读到的每一篇文章都不太清楚这两者之间的区别。哪些用例适用于每个响应?


丹尼尔·欧文的一个明确解释:

There's a problem with 401 Unauthorized, the HTTP status code for authentication errors. And that’s just it: it’s for authentication, not authorization.
Receiving a 401 response is the server telling you,"you aren’t
authenticated–either not authenticated at all or authenticated
incorrectly–but please reauthenticate and try again." To help you out,
it will always include a WWW-Authenticate header that describes how
to authenticate.

This is a response generally returned by your web server, not your web
application.

It’s also something very temporary; the server is asking you to try
again.

So, for authorization I use the 403 Forbidden response. It’s
permanent, it’s tied to my application logic, and it’s a more concrete
response than a 401.

Receiving a 403 response is the server telling you,"I’m sorry. I know
who you are–I believe who you say you are–but you just don’t have
permission to access this resource. Maybe if you ask the system
administrator nicely, you’ll get permission. But please don’t bother
me again until your predicament changes."

In summary, a 401 Unauthorized response should be used for missing
or bad authentication, and a 403 Forbidden response should be used
afterwards, when the user is authenticated but isn’t authorized to
perform the requested operation on the given resource.

另一种关于如何使用HTTP状态代码的很好的图形格式。

enter image description here


见RFC2616:

401未经授权:

If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.

403禁止:

The server understood the request, but is refusing to fulfill it.

更新

从您的用例来看,用户似乎没有经过身份验证。我要退401。

编辑:rfc2616已过时,请参阅rfc7231和rfc7235。


其他答案缺失的是,必须理解的是,在RFC2616上下文中的身份验证和授权仅指RFC2617的HTTP身份验证协议。HTTP状态代码不支持由RFC2617之外的方案进行身份验证,并且在决定是否使用401或403时不考虑该验证。

简明扼要

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

也就是说,如果您有自己的Roll登录过程并且从不使用HTTP身份验证,403总是正确的响应,401永远不应该被使用。

详细和深入

来自RFC2616

10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8).

10.4.4 403 Forbidden
The server understood the request but is refusing to fulfil it. Authorization will not help and the request SHOULD NOT be repeated.

首先要记住的是,本文档上下文中的"身份验证"和"授权"专门指的是来自RFC2617的HTTP身份验证协议。它们不涉及您自己使用登录页面创建的任何Roll身份验证协议等。我将使用"登录"来指由RFC2617以外的方法进行的身份验证和授权。

所以真正的区别不是问题是什么,或者即使有解决方案。区别在于服务器期望客户机接下来做什么。

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

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

编辑:rfc2616已过时,请参阅rfc7231和rfc7235。


根据RFC 2616(HTTP/1.1),403在以下情况下发送:

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   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如果资源不存在(或不愿意透露任何信息)

未授权:状态代码(401),表示请求需要身份验证,通常这意味着用户需要登录(会话)。服务器未知的用户/代理。可以与其他凭据一起重复。注意:这让人困惑,因为它应该被命名为"未经身份验证"而不是"未经授权"。如果会话过期,登录后也可能发生这种情况。特殊情况:可以用404代替404,以避免暴露资源的存在或不存在(credits@gingercodeninja)

禁止:状态代码(403),表示服务器理解请求,但拒绝完成请求。服务器已知的用户/代理,但没有足够的凭据。重复请求将不起作用,除非凭证发生更改,这在短时间内是不太可能的。特殊情况:可以用404代替404,以避免暴露资源的存在或不存在(credits@gingercodeninja)

未找到:状态代码(404),指示请求的资源不可用。已知的用户/代理,但服务器不会显示有关该资源的任何信息,就像它不存在一样。重复不起作用。这是404的一个特殊用途(例如,Github就是这样做的)。


假设正在使用HTTP身份验证(www authenticate和authorization headers),如果作为另一个用户进行身份验证将授予对请求资源的访问权,则应返回401 unauthorized。

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

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

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

3.1. 401 Unauthorized

The 401 (Unauthorized) status code indicates that the request has
not been applied because it lacks valid authentication credentials
for the target resource. The origin server MUST send a
WWW-Authenticate header field (Section 4.4) containing at least one
challenge applicable to the target resource. If the request
included authentication credentials, then the 401 response
indicates that authorization has been refused for those
credentials. The client MAY repeat the request with a new or
replaced Authorization header field (Section 4.1). If the 401
response contains the same challenge as the prior response, and the
user agent has already attempted authentication at least once, then
the user agent SHOULD present the enclosed representation to the
user, since it usually contains relevant diagnostic information.

403(和404)的语义随时间而变化。这是从1999年开始的(RFC 2616):

10.4.4 403 Forbidden

The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.

2014年,RFC7231(超文本传输协议(HTTP/1.1):语义和内容)改变了403的含义:

6.5.3. 403 Forbidden

The 403 (Forbidden) status code indicates that the server
understood the request but refuses to authorize it. A server that
wishes to make public why the request has been forbidden can
describe that reason in the response payload (if any).

If authentication credentials were provided in the request, the
server considers them insufficient to grant access. The client
SHOULD NOT automatically repeat the request with the same
credentials. The client MAY repeat the request with new or different
credentials. However, a request might be forbidden for reasons
unrelated to the credentials.

An origin server that wishes to"hide" the current existence of a
forbidden target resource MAY instead respond with a status code of
404 (Not Found).

因此,403(或404)现在可能意味着任何事情。提供新凭据可能会有所帮助…或者可能不会。

我相信这一点发生变化的原因是RFC2616假设在当今的Web应用程序实际中使用HTTP身份验证来构建自定义的身份验证方案,例如表单和cookie。


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

OWASP提供了关于攻击者如何将此类信息用作攻击的一部分的更多信息。


这个问题一段时间前就被问到了,但人们的思想还在继续。

本草案第6.5.3节(由Fielding和Reschke编写)给出的状态代码403与RFC 2616中的状态代码含义略有不同。

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

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

6.5.3. 403 Forbidden

The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it. A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any).

If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.

An origin server that wishes to"hide" the current existence of a forbidden target resource MAY instead respond with a status code of 404 (Not Found).

无论您使用什么约定,重要的是在您的站点/API中提供一致性。


DR

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

实例

如果Apache需要认证(通过.htaccess),而您点击Cancel,它将用401 Authorization Required响应。

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

RFC(2616第10节)401未经授权(10.4.2)

含义1:需要认证

The request requires user authentication. ...

含义2:认证不足

... If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. ...

号403禁止(10.4.4)

含义:与认证无关

... Authorization will not help ...

更多详细信息:

  • The server understood the request, but is refusing to fulfill it.

  • It SHOULD describe the reason for the refusal in the entity

  • The status code 404 (Not Found) can be used instead

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


they are not logged in or do not belong to the proper user group

您已经陈述了两个不同的案例;每个案例都应该有不同的回答:

  • 如果他们根本没有登录,你应该返回401未经授权
  • 如果它们已登录但不属于正确的用户组,则应返回403 Forbidden
  • 基于收到的回复意见的RFC说明:

    如果用户没有登录,那么他们是未经身份验证的,HTTP等价物是401,在RFC中被错误地称为未经授权。如第10.4.2节所述,401未经授权:

    "The request requires user authentication."

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


    我认为重要的是要考虑到,对于浏览器来说,401会启动一个身份验证对话框,让用户输入新的凭证,而403则不会。浏览器认为,如果返回401,那么用户应该重新进行身份验证。所以401代表无效身份验证,403代表缺少权限。

    在这种逻辑下,有些情况下,认证或授权会返回一个错误,其中重要的短语用粗体显示。

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

    401:客户端应该指定凭据。

    • 指定的凭据的格式无效。

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

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

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

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

    401:同样,客户机应该指定有效的凭证。

    • 指定的凭据已过期。

    401:一般来说,这和拥有无效的凭证差不多,所以客户机应该指定有效的凭证。

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

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

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

    403:这与凭据无关,因此指定有效凭据没有帮助。

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

    403:如果客户端被阻止,则指定新凭据将不起任何作用。


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

    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


    考虑到最新的RFC关于这个问题(7231和7235),用例看起来相当清楚(斜体字添加):

    • 401用于未经身份验证("缺乏有效的身份验证"),即"我不知道你是谁,或者我不相信你说的是谁"。

    401 Unauthorized

    The 401 (Unauthorized) status code indicates that the request has not
    been applied because it lacks valid authentication credentials for
    the target resource. The server generating a 401 response MUST send
    a WWW-Authenticate header field (Section 4.1) containing at least one
    challenge applicable to the target resource.

    If the request included authentication credentials, then the 401
    response indicates that authorization has been refused for those
    credentials. The user agent MAY repeat the request with a new or
    replaced Authorization header field (Section 4.2). If the 401
    response contains the same challenge as the prior response, and the
    user agent has already attempted authentication at least once, then
    the user agent SHOULD present the enclosed representation to the
    user, since it usually contains relevant diagnostic information.

    • 403表示未经授权("拒绝授权");即"我知道您是谁,但您没有访问此资源的权限。"

    403 Forbidden

    The 403 (Forbidden) status code indicates that the server understood
    the request but refuses to authorize it. A server that wishes to
    make public why the request has been forbidden can describe that
    reason in the response payload (if any).

    If authentication credentials were provided in the request, the
    server considers them insufficient to grant access. The client
    SHOULD NOT automatically repeat the request with the same
    credentials. The client MAY repeat the request with new or different
    credentials. However, a request might be forbidden for reasons
    unrelated to the credentials.

    An origin server that wishes to"hide" the current existence of a
    forbidden target resource MAY instead respond with a status code of
    404 (Not Found).


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

    您自己的登录问题(应用程序)似乎有问题。

    在这种情况下,不登录不足以发送401或403,除非使用http auth与登录页(不绑定到设置http auth)。听起来您可能在寻找一个"201已创建",有一个滚动您自己的登录屏幕(而不是请求的资源)来访问一个文件。这说明:

    "我听到了,它在这里,但是你可以试试这个(你不能看到它)"。