对于存在但用户没有足够权限(他们未登录或不属于正确的用户组)的网页,要提供的正确HTTP响应是什么?

401未授权?403禁止?还有别的吗?

到目前为止,我读到的每一篇文章都不太清楚两者之间的区别。每个响应都适合哪些用例?


当前回答

其含义如下:

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

403:用户的角色或权限不允许访问请求的资源,例如,用户不是管理员,请求的页面是管理员的。

注意:从技术上讲,403是401的超集,因为给未经认证的用户403也是合法的。无论如何,区分更有意义。

其他回答

我对它的看法与公认的答案略有不同。

当认证失败时返回403,当授权失败时返回401,这似乎更符合语义和逻辑。

我的理由如下:

当您请求认证时,您有权提出该请求。你需要这样做,否则一开始就没有人能够通过认证。

如果您的身份验证失败,您将被禁止,这是有意义的。

另一方面,被禁止者也可以申请授权,但假设您已通过身份验证,但无权访问特定端点。返回401 Unauthorized似乎更有意义。

对于失败的身份验证尝试,Spring Boot的安全性返回403

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

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

在这种情况下,仅仅不登录不足以发送401或403,除非您使用HTTP Auth与登录页面(与设置HTTP Auth无关)。听起来您可能正在寻找一个“201已创建”,其中有一个滚动您自己的登录屏幕(而不是请求的资源),用于应用程序级访问文件。上面写着:

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

401未经授权:我不知道你是谁。这是一个身份验证错误。403禁止:我知道你是谁,但你没有访问此资源的权限。这是一个授权错误。

丹尼尔·欧文(Daniel Irvine)的明确解释[原始链接]:

401 Unauthorized(401未授权)存在问题,这是身份验证错误的HTTP状态代码。这就是它:它用于身份验证,而不是授权。收到401响应时,服务器会告诉你,“你不是已验证–完全未验证或已验证不正确–但请重新验证并重试。”为了帮助您,它将始终包含一个WWW Authenticate标头,描述如何以进行身份验证。这是通常由web服务器而不是web返回的响应应用这也是非常暂时的;服务器要求您尝试再一次因此,为了获得授权,我使用403 Forbidden响应。它是永久性的,它与我的应用程序逻辑有关,而且更具体响应大于401。收到403响应时,服务器会告诉你:“对不起,我知道你是谁——我相信你说的你是谁,但你只是没有访问此资源的权限。也许如果你问系统管理员很好,你会得到许可的。但请不要打扰直到你的困境改变。”总之,401未经授权的响应应用于缺失或认证错误,应使用403禁止响应之后,当用户经过身份验证但未被授权对给定资源执行请求的操作。

另一种很好的图片格式,说明如何使用http状态代码。

  +-----------------------
  | RESOURCE EXISTS ? (if private it is often checked AFTER auth check)
  +-----------------------
    |       |
 NO |       v YES
    v      +-----------------------
   404     | IS LOGGED-IN ? (authenticated, aka user session)
   or      +-----------------------
   401        |              |
   403     NO |              | YES
   3xx        v              v
              401            +-----------------------
       (404 no reveal)       | CAN ACCESS RESOURCE ? (permission, authorized, ...)
              or             +-----------------------
             redirect          |            |
             to login       NO |            | YES
                               |            |
                               v            v
                               403          OK 200, redirect, ...
                      (or 404: no reveal)
                      (or 404: resource does not exist if private)
                      (or 3xx: redirection)

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

404如果资源是公共的且不存在或3xx重定向否则:401如果未登录或会话已过期403如果用户没有访问资源的权限(文件、json…)404如果资源不存在或不愿意透露任何信息,或3xx重定向

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

禁止:状态代码(403),表示服务器理解请求但拒绝执行。服务器知道用户/代理,但没有足够的凭据。除非凭据更改,否则重复请求将不起作用,这在短时间内是非常不可能的。特殊情况:可以使用404代替404,以避免在显示资源的存在暴露敏感数据或向攻击者提供有用信息的情况下显示资源(credits@jiangCodeNinja)的存在或不存在。

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

如@ChrisH所述,有几个3xx重定向选项(301、302、303、307或根本不重定向,使用401):

HTTP重定向代码之间的差异浏览器缓存HTTP 301多长时间?重定向到登录页面时,正确的HTTP状态代码是什么?302和307重定向之间有什么区别?