对于存在的网页,但对于没有足够权限的用户(他们未登录或不属于正确的用户组),要提供的正确HTTP响应是什么? 401? 403?别的什么?到目前为止,我对每个人的看法都不太清楚。哪些用例适合每个响应?
来自Daniel Irvine的明确解释:
401 Unauthorized存在问题,这是用于身份验证错误的HTTP状态代码。就是这样:它是用于身份验证,而不是授权。收到401响应是服务器告诉您,“您未经过身份验证 - 根本未经过身份验证或未正确验证 - 但请重新进行身份验证并重试。”为了帮助您,它将始终包含一个描述的WWW-Authenticate标头如何进行身份验证。
这是您的Web服务器通常返回的响应,而不是您的Web应用程序。
这也是非常暂时的;服务器要求您再试一次。
因此,对于授权,我使用403 Forbidden响应。它是永久性的,它与我的应用程序逻辑相关联,而且它比401更具体。
收到403响应是服务器告诉你,“对不起。我知道你是谁 - 我相信你说的是谁 - 但你只是没有权限访问这个资源。也许如果您很好地询问系统管理员,您将获得许可。但是,在你的困境发生变化之前,请不要再打扰我了。“
总之,401 Unauthorized响应应该用于丢失或错误的身份验证,之后,当用户通过身份验证但无权对给定资源执行请求的操作时,应使用403 Forbidden响应。
关于如何使用http状态代码的另一个nice pictorial format。
他们没有登录或不属于正确的用户组
你说过两种不同的情况;每个案例应该有不同的回应:
根据收到的回复评论RFC:
如果用户未登录,则他们未经过身份验证,其HTTP等效值为401,并且在RFC中误导性地称为“未授权”。正如section 10.4.2声明的401 Unauthorized:
“该请求需要用户身份验证。”
如果您未经身份验证,则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
401:我不知道你是谁。这是一个验证错误。 403:我知道你是谁。但您无权访问此资源。这是授权错误。
鉴于有关此问题的最新RFC(7231和7235),用例似乎非常清楚(斜体添加):
401未经授权
401(未授权)状态代码表示尚未应用请求,因为它缺少目标资源的有效身份验证凭据。生成401响应的服务器必须发送WWW-Authenticate头字段(第4.1节),其中包含至少一个适用于目标资源的质询。
如果请求包含身份验证凭据,则401响应表示已拒绝授权这些凭据。用户代理可以使用新的或替换的Authorization头字段重复请求(第4.2节)。如果401响应包含与先前响应相同的挑战,并且用户代理已经尝试过至少一次认证,那么用户代理应该将所包含的表示呈现给用户,因为它通常包含相关的诊断信息。
403禁止
403(禁止)状态代码表示服务器理解请求但拒绝授权。希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话)。
如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限。客户端不应该使用相同的凭据自动重复请求。客户端可以使用新的或不同的凭据重复请求。但是,出于与凭证无关的原因,可能会禁止请求。
希望“隐藏”禁止目标资源的当前存在的源服务器可以以状态代码404(未找到)来响应。
在401 vs 403的情况下,这已被多次回答。这本质上是一个“HTTP请求环境”辩论,而不是“应用程序”辩论。
滚动自己的登录问题(应用程序)似乎存在问题。
在这种情况下,除非您使用HTTP Auth vs登录页面(不依赖于设置HTTP Auth),否则仅仅登录不足以发送401或403。听起来您可能正在寻找“201 Created”,其中存在自己的滚动登录屏幕(而不是请求的资源),用于应用程序级别的文件访问。这说:
“我听到你了,它就在这里,但试试这个(你不能看到它)”
缺少其他答案的一点是,必须理解RFC 2616上下文中的身份验证和授权仅涉及RFC 2617的HTTP身份验证协议.HTTP状态代码不支持RFC2617之外的方案的身份验证,因此不予考虑在决定是否使用401或403时。
Unauthorized表示客户端未通过RFC2617身份验证,并且服务器正在启动身份验证过程。 Forbidden表示客户端已通过RFC2617身份验证且没有授权,或者服务器不支持所请求资源的RFC2617。
这意味着如果您拥有自己的滚动登录过程并且从不使用HTTP身份验证,则403始终是正确的响应,并且永远不应使用401。
来自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标准和定义。
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)
检查通常按以下顺序进行:
UNAUTHORIZED:状态代码(401),表示请求需要身份验证,通常这意味着用户需要登录(会话)。用户/代理未知的服务器。可以重复其他凭据。注意:这很令人困惑,因为它应该被命名为“未经身份验证”而不是“未经授权”。如果会话过期,这也可能在登录后发生。特例:可以代替404使用,以避免泄露资源的存在或不存在(信用@gingerCodeNinja)
FORBIDDEN:状态代码(403),表示服务器理解请求但拒绝履行请求。用户/代理服务器已知但凭据不足。除非凭据更改,否则重复请求将不起作用,这在短时间内不太可能发生。特例:可以代替404使用,以避免泄露资源的存在或不存在(信用@gingerCodeNinja)
NOT FOUND:状态代码(404),表示请求的资源不可用。用户/代理已知,但服务器不会透露有关资源的任何信息,就好像它不存在一样。重复不起作用。这是404的特殊用法(github就是这样做的)。
根据RFC 2616(HTTP / 1.1)403发送时间:
服务器理解请求,但拒绝履行请求。授权无效,请求不应重复。如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)
换句话说,如果客户端通过身份验证可以访问资源,则应该发送401。
假设正在使用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构建自定义身份验证方案。
这是一个较老的问题,但从未真正提出的一个选择是返回404.从安全角度来看,最高投票的答案会受到潜在的information leakage vulnerability的影响。例如,假设所讨论的安全网页是系统管理页面,或者更常见的是,是用户无权访问的系统中的记录。理想情况下,您不希望恶意用户甚至不知道那里有页面/记录,更不用说他们没有访问权限了。当我构建这样的东西时,我会尝试在内部日志中记录未经验证/未经授权的请求,但返回404。
OWASP有一些关于攻击者如何使用此类信息作为攻击的一部分的more information。
这个问题前一段时间被问过,但人们的想法还在继续。
本草案中的Section 6.5.3(由Fielding和Reschke撰写)给出了状态代码403与RFC 2616中记录的含义略有不同的含义。
它反映了许多流行的Web服务器和框架所采用的身份验证和授权方案中发生的情况。
我强调了我认为最突出的一点。
6.5.3。 403禁止
403(禁止)状态代码表示服务器理解请求但拒绝授权。希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话)。
如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限。客户端不应该使用相同的凭据重复请求。客户端可以使用新的或不同的凭据重复请求。但是,出于与凭证无关的原因,可能会禁止请求。
希望“隐藏”禁止目标资源的当前存在的源服务器可以以状态代码404(未找到)来响应。
无论您使用哪种惯例,重要的是在您的网站/ API中提供一致性。
如果apache需要身份验证(通过.htaccess
),并且你点击Cancel
,它将响应401 Authorization Required
如果nginx找到一个文件,但没有访问权限(用户/组)来读取/访问它,它将响应403 Forbidden
含义1:需要进行身份验证
该请求需要用户身份验证。 ...
含义2:认证不足
...如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据。 ...
含义:与身份验证无关
......授权无济于事......
更多细节: