对于存在但用户没有足够权限(他们未登录或不属于正确的用户组)的网页,要提供的正确HTTP响应是什么?
401未授权?403禁止?还有别的吗?
到目前为止,我读到的每一篇文章都不太清楚两者之间的区别。每个响应都适合哪些用例?
对于存在但用户没有足够权限(他们未登录或不属于正确的用户组)的网页,要提供的正确HTTP响应是什么?
401未授权?403禁止?还有别的吗?
到目前为止,我读到的每一篇文章都不太清楚两者之间的区别。每个响应都适合哪些用例?
当前回答
在401对403的情况下,这已经得到了多次回答。这本质上是一场“HTTP请求环境”辩论,而不是“应用程序”辩论。
您自己的登录问题(应用程序)似乎有问题。
在这种情况下,仅仅不登录不足以发送401或403,除非您使用HTTP Auth与登录页面(与设置HTTP Auth无关)。听起来您可能正在寻找一个“201已创建”,其中有一个滚动您自己的登录屏幕(而不是请求的资源),用于应用程序级访问文件。上面写着:
“我听到了,它在这里,但试试这个(不允许你看到)”
其他回答
其他答案缺少的是,必须理解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的情况下,这已经得到了多次回答。这本质上是一场“HTTP请求环境”辩论,而不是“应用程序”辩论。
您自己的登录问题(应用程序)似乎有问题。
在这种情况下,仅仅不登录不足以发送401或403,除非您使用HTTP Auth与登录页面(与设置HTTP Auth无关)。听起来您可能正在寻找一个“201已创建”,其中有一个滚动您自己的登录屏幕(而不是请求的资源),用于应用程序级访问文件。上面写着:
“我听到了,它在这里,但试试这个(不允许你看到)”
+----------------------- | 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重定向之间有什么区别?
我对它的看法与公认的答案略有不同。
当认证失败时返回403,当授权失败时返回401,这似乎更符合语义和逻辑。
我的理由如下:
当您请求认证时,您有权提出该请求。你需要这样做,否则一开始就没有人能够通过认证。
如果您的身份验证失败,您将被禁止,这是有意义的。
另一方面,被禁止者也可以申请授权,但假设您已通过身份验证,但无权访问特定端点。返回401 Unauthorized似乎更有意义。
对于失败的身份验证尝试,Spring Boot的安全性返回403
401未经授权:我不知道你是谁。这是一个身份验证错误。403禁止:我知道你是谁,但你没有访问此资源的权限。这是一个授权错误。