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

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

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


当前回答

401响应是指以下之一:

缺少访问令牌。访问令牌已过期、吊销、格式错误或无效。

403响应另一方面意味着访问令牌确实有效,但用户没有执行所请求的操作的适当权限。

其他回答

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

你陈述了两种不同的情况;每种情况都应有不同的反应:

如果他们根本没有登录,您应该返回401未授权如果他们已登录但不属于正确的用户组,则应返回403禁止

根据收到的对此答案的评论,请注意RFC:

如果用户未登录,他们将被取消身份验证,其HTTP等效值为401,在RFC中被错误地称为“未授权”。如第10.4.2节所述,401未经授权:

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

如果您未经认证,401是正确的响应。然而,如果您未经授权,在语义正确的意义上,403是正确的响应。

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

403 Forbidden用于禁止所有人访问资源或限制访问给定网络或仅允许通过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假设在实践中,当今天的Web应用程序使用例如表单和cookie构建自定义身份验证方案时,将使用HTTP身份验证。

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

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

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

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

我的理由如下:

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

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

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

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

你又是谁??(程序员走进一个没有ID或ID无效的酒吧)

403:太好了,又是你。我盯着你了。走吧,离开这里。(程序员走进一家86岁的酒吧)