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

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

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


当前回答

其他答案缺少的是,必须理解RFC 2616上下文中的认证和授权仅指RFC 2617的HTTP认证协议。HTTP状态代码不支持RFC2617以外的方案进行认证,并且在决定是否使用401或403时不考虑。

Brief和Terse

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

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

详细和深入

来自RFC2616

10.4.2 401未授权请求需要用户身份验证。响应必须包括WWW Authenticate报头字段(第14.47节),该字段包含适用于所请求资源的质询。客户端可以使用适当的授权头字段重复请求(第14.8节)。

and

10.4.4 403禁止服务器理解该请求,但拒绝履行。授权不会有帮助,不应重复该请求。

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

因此,真正的区别不在于问题是什么,甚至不在于是否有解决方案。区别在于服务器希望客户端接下来做什么。

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

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


编辑:RFC2616已过时,请参阅RFC7231和RFC7235。

其他回答

英语:

401

您可能被允许访问,但出于某种原因否认。例如密码错误?请使用正确的请求重试你会得到成功的回应。

403

你永远不被允许。你的名字不在名单上,你不会一旦进入,离开,不要发送重试请求,它将被拒绝,总是走开。

考虑到最新的RFC(7231和7235),用例似乎非常清楚(添加了斜体):

401表示未经认证(“缺少有效认证”);即“我不知道你是谁,或者我不相信你是你说的那样。”

401未授权

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

如果请求包括认证证书,则401响应表明授权已被拒绝资格证书用户代理可以使用新的或替换了Authorization头字段(第4.2节)。如果401响应包含与先前响应相同的挑战用户代理已经至少尝试了一次身份验证,然后用户代理应向因为它通常包含相关的诊断信息。

403表示未经授权(“拒绝授权”);即“我知道你是谁,但你无权访问此资源。”

403禁止

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

如果请求中提供了身份验证凭据服务器认为它们不足以授予访问权限。客户不应自动重复相同的请求资格证书客户可以用新的或不同的重复请求资格证书然而,出于某些原因,请求可能被禁止与证书无关。

希望“隐藏”当前存在的禁用的目标资源可能会以状态代码响应404(未找到)。

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

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

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

服务器理解该请求,但拒绝履行该请求。授权没有帮助,不应重复该请求。如果请求方法不是HEAD,并且服务器希望公开请求未完成的原因,则应在实体中描述拒绝的原因。如果服务器不希望向客户端提供此信息,则可以使用状态代码404(未找到)

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

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

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