首页 文章

403 Forbidden vs 401 Unauthorized HTTP响应

提问于
浏览
2060

对于存在的网页,但对于没有足够权限的用户(他们未登录或不属于正确的用户组),要提供的正确HTTP响应是什么? 401? 403?别的什么?到目前为止,我对每个人的看法都不太清楚 . 哪些用例适合每个响应?

14 回答

  • 20

    来自Daniel Irvine的明确解释:

    401 Unauthorized存在问题,即身份验证错误的HTTP状态代码 . 就是这样:它用于身份验证,而不是授权 . 收到401响应是服务器告诉您,“您未经过身份验证 - 要么未经过身份验证,要么未经过身份验证 - 但请重新进行身份验证并重试 . ”为了帮助您,它将始终包含一个描述的WWW-Authenticate标头如何进行身份验证 . 这是您的Web服务器通常返回的响应,而不是您的Web应用程序 . 这也是非常暂时的;服务器要求您再试一次 . 因此,对于授权,我使用403 Forbidden响应 . 它是永久性的,它与我的应用程序逻辑联系在一起,而且它比401更具体的响应 . 收到403响应是服务器告诉你,“我很抱歉 . 我知道你是谁 - 我相信你说的是谁 - 但你只是没有权限访问这个资源 . 也许如果您很好地询问系统管理员,您将获得许可 . 但是,在您的困境发生变化之前,请不要再打扰我了 . “总之,应该使用401 Unauthorized响应进行遗漏或不良认证,之后应该使用403 Forbidden响应,当用户通过身份验证但未经授权在给定资源上执行请求的操作 .

    另一个nice pictorial format应该如何使用http状态代码 .

  • 102

    RFC2616

    401未经授权:

    如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据 .

    403禁止:

    服务器理解请求,但拒绝履行请求 .

    Update

    从您的用例来看,似乎用户未经过身份验证 . 我会回401 .


    编辑:RFC2616已过时,请参阅RFC7231RFC7235 .

  • 9

    缺少其他答案的一点是,必须理解RFC 2616上下文中的身份验证和授权仅涉及RFC 2617的HTTP身份验证协议.HTTP状态代码不支持RFC2617以外的方案的身份验证,因此不予考虑在决定是否使用401或403 ..

    简要和简短

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

    这意味着如果您拥有自己的滚动登录过程并且从不使用HTTP身份验证,则403始终是正确的响应,并且永远不应使用401 .

    详细而深入

    来自RFC2616

    10.4.2 401 Unauthorized请求需要用户身份验证 . 响应必须包含WWW-Authenticate头字段(第14.47节),其中包含适用于所请求资源的质询 . 客户端可以使用合适的Authorization头字段重复请求(第14.8节) .

    10.4.4 403 Forbidden服务器理解请求,但拒绝履行请求 . 授权无效,请求不应重复 .

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

    所以真正的区别不在于问题是什么,甚至是否有解决方案 . 不同之处在于服务器期望客户端下一步做什么 .

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

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


    编辑:RFC2616已过时,请参阅RFC7231RFC7235 .

  • 23

    根据RFC 2616(HTTP / 1.1)403发送时间:

    服务器理解请求,但拒绝履行请求 . 授权无效,请求不应重复 . 如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因 . 如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)

    换句话说,如果客户端通过身份验证可以访问资源,则应该发送401 .

  • 345
    GET, resource exists ?
        |      |
     NO |      | YES
        v      v
       404     Is authenticated (logged-in) ?
                 |              |
              NO |              | YES
                 v              v
                 401            Can access resource (has permissions) ?
               (or: 404)        |            |
               or 301        NO |            | YES
               redirect         v            v
               to login        403           OK 200, 301, ...
    

    支票通常按以下顺序进行:

    • 401如果未登录或会话已过期

    • 403如果用户没有访问资源的权限

    • 404如果资源不存在

    UNAUTHORIZED :状态代码(401),表示请求需要 authentication ,通常这意味着用户需要登录(会话) . 用户/代理未知的服务器 . 可以重复其他凭据 . 注意:这很令人困惑,因为它应该被命名为'unauthenticated'而不是'unauthorized' . 如果会话过期,这也可能在登录后失败 .

    FORBIDDEN :状态代码(403),表示服务器理解了请求但拒绝履行请求 . 用户/代理已知服务器但具有 insufficient credentials . 除非凭据更改,否则重复请求将不起作用,这在短时间内不太可能发生 .

    NOT FOUND :状态代码(404),表示请求的资源不可用 . 用户/代理已知,但服务器不会透露有关资源的任何信息,就好像它不存在一样 . 重复不起作用 . 这是404的特殊用法(github就是这样做的) .

  • 261

    如果作为另一个用户进行身份验证将授予对所请求资源的访问权限,则应返回401 Unauthorized . 403 Forbidden主要用于禁止向所有人访问资源或仅限于给定网络或只允许通过SSL访问资源,只要它与身份验证无关 .

    来自RFC 7235(超文本传输协议(HTTP / 1.1):身份验证):

    3.1 . 401 Unauthorized 401(未授权)状态代码表示该请求尚未应用,因为它缺少目标资源的有效身份验证凭据 . 源服务器必须发送WWW-Authenticate头字段(第4.4节),其中包含至少一个适用于目标资源的质询 . 如果请求包含身份验证凭据,则401响应表示已拒绝授权这些凭据 . 客户端可以使用新的或替换的Authorization头字段重复请求(第4.1节) . 如果401响应包含与先前响应相同的挑战,并且用户代理已经尝试过至少一次认证,那么用户代理应该将所包含的表示呈现给用户,因为它通常包含相关的诊断信息 .

    这是来自RFC 2616:

    10.4.4 403 Forbidden服务器理解请求,但拒绝履行请求 . 授权无效,请求不应重复 . 如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因 . 如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到) .

    编辑:RFC 7231(超文本传输协议(HTTP / 1.1):语义和内容)更改403的含义:

    6.5.3 . 403 Forbidden 403(Forbidden)状态代码表示服务器理解请求但拒绝授权 . 希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话) . 如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限 . 客户端不应该使用相同的凭据自动重复请求 . 客户端可以使用新的或不同的凭据重复请求 . 但是,出于与凭证无关的原因,可能会禁止请求 . 希望“隐藏”当前存在的禁止目标资源的原始服务器可以用状态代码404(未找到)来响应 .

    因此,403现在可能意味着什么 . 提供新凭据可能会有所帮助......或者可能没有 .

  • 2

    这是一个较老的问题,但从未真正提出的一个选择是返回404.从安全角度来看,最高投票的答案会受到潜在的影响information leakage vulnerability . 例如,假设所讨论的安全网页是系统管理页面,或者更常见的是,它是一个记录一个系统,用户不希望恶意用户甚至知道有访问权限 . 当我'm building something like this, I'll尝试在内部日志中记录未经身份验证/未经授权的请求时,但返回404 .

    OWASP有一些more information关于攻击者如何将这类信息用作攻击的一部分 .

  • 0

    这个问题前一段时间被问过,但人们的想法仍在继续 .

    本草案中的Section 6.5.3(由Fielding和Reschke撰写)给出了状态代码403与RFC 2616中记录的含义略有不同的含义 .

    它反映了许多流行的Web服务器和框架所采用的身份验证和授权方案中发生的情况 .

    我强调了我认为最突出的一点 .

    6.5.3 . 403 Forbidden 403(Forbidden)状态代码表示服务器理解请求但拒绝授权 . 希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话) . 如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限 . 客户端不应该使用相同的凭据重复请求 . 客户端可以使用新的或不同的凭据重复请求 . 但是,出于与凭证无关的原因,可能会禁止请求 . 希望“隐藏”当前存在的禁止目标资源的原始服务器可以用状态代码404(未找到)来响应 .

    无论您使用何种惯例,重要的是在您的网站/ API中提供一致性 .

  • 3073

    TL; DR

    • 401:拒绝与身份验证有关

    • 403:拒绝与身份验证无关

    实际例子

    如果 apache 需要身份验证(通过 .htaccess ),并且您点击 Cancel ,它将以 401 Authorization Required 回复

    如果 nginx 找到一个文件,但没有访问权限(用户/组)来读取/访问它,它将以 403 Forbidden 响应

    RFC(2616第10节)

    401未经授权(10.4.2)

    含义1: Need to authenticate

    该请求需要用户身份验证 . ...

    含义2: Authentication insufficient

    ...如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据 . ...

    403禁止(10.4.4)

    含义: Unrelated to authentication

    ......授权无济于事......

    更多细节:

    • 服务器理解请求,但拒绝履行请求 .

    • 它应该描述实体拒绝的原因

    • 可以使用状态代码404(未找到)代替

    (如果服务器想要从客户端保留此信息)

  • 9

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

    你说过两种不同的情况;每个案例应该有不同的回应:

    • 如果他们根本没有登录,你应该返回 401 Unauthorized

    • 如果他们已登录但不属于正确的用户组,则应返回 403 Forbidden

    根据收到的回复评论RFC:

    如果用户未登录,则他们未经过身份验证,其HTTP等效值为401,并且在RFC中误导性地称为“未授权” . 401 Unauthorizedsection 10.4.2状态:

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

    如果您未经身份验证,则401是正确的答案 . 但是,如果你是未经授权的,从语义上来看,403是正确的反应 .

  • -4

    我认为重要的是要考虑到,对于浏览器,401启动用户输入新凭证的验证对话框,而403则不然 . 浏览器认为,如果返回401,则用户应重新进行身份验证 . 因此401代表无效认证,而403代表缺乏许可 .

    以下是在该逻辑下的一些情况,其中将从身份验证或授权返回错误,重要的短语加粗 .

    • 资源需要身份验证,但 no credentialsspecified .

    401 :客户端应指定凭据 .

    • 指定的凭据位于 invalid format 中 .

    400 :既不是401也不是403,因为语法错误应该总是返回400 .

    • 指定的凭据引用了 user does not exist .

    401 :客户端应指定有效凭据 .

    • 指定的 credentialsinvalid 但指定了有效用户(或者不要将用户指定为指定用户) .

    401 :同样,客户端应指定有效凭据 .

    • 指定的 credentialsexpired .

    401 :这通常与通常无效凭据相同,因此客户端应指定有效凭据 .

    • 指定的凭据完全有效,但不是 suffice 特定的 resource ,尽管具有更多权限的凭证可能是 .

    403 :指定有效凭据不会授予对当前凭据的资源访问权限已经有效,但只是没有权限 .

    • 无论凭据如何, resource 都是 inaccessible .

    403 :这与凭据无关,因此指定有效凭据无济于事 .

    • 指定的凭据完全有效,但特定的 clientblocked 使用它们 .

    403 :如果客户端被阻止,则指定新凭据将不会执行任何操作 .

  • 3

    这比我在这里的任何地方都简单,所以:

    401:您需要HTTP基本身份验证才能看到这一点 .

    403:您无法看到这一点,HTTP基本身份验证也无济于事 .

    如果用户只需要使用您站点的标准HTML登录表单登录,则401将不合适,因为它特定于HTTP基本身份验证 .

    我不建议使用403拒绝访问 /includes 这样的内容,因为就网络而言,这些资源根本不存在,因此应该是404 .

    这留下403为“你需要登录” .

    换句话说,403表示“此资源需要除HTTP基本身份验证之外的某种形式的身份验证” .

    https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2

  • 74

    鉴于有关此问题的最新RFC(72317235),用例似乎非常清楚(斜体添加):

    • 401适用于unauthenticated("lacks valid authentication");即'I don'知道你是谁,或者我不知道't trust you are who you say you are.'

    401 Unauthorized 401(未授权)状态代码表示该请求尚未应用,因为它缺少目标资源的有效身份验证凭据 . 生成401响应的服务器必须发送包含至少一个适用于目标资源的质询的WWW-Authenticate头字段(第4.1节) . 如果请求包含身份验证凭据,则401响应表示已拒绝授权这些凭据 . 用户代理可以使用新的或替换的Authorization头字段重复该请求(第4.2节) . 如果401响应包含与先前响应相同的挑战,并且用户代理已经尝试过至少一次认证,那么用户代理应该将所包含的表示呈现给用户,因为它通常包含相关的诊断信息 .

    • 403适用于unauthorized("refuses to authorize");即'I know who you are, but you don't有权访问此资源 .

    403 Forbidden 403(Forbidden)状态代码表示服务器理解请求但拒绝授权 . 希望公开请求被禁止的服务器可以在响应有效负载中描述该原因(如果有的话) . 如果请求中提供了身份验证凭据,则服务器认为它们不足以授予访问权限 . 客户端不应该使用相同的凭据自动重复请求 . 客户端可以使用新的或不同的凭据重复请求 . 但是,出于与凭证无关的原因,可能会禁止请求 . 希望“隐藏”当前存在的禁止目标资源的原始服务器可以用状态代码404(未找到)来响应 .

  • 38

    在401 vs 403的情况下,这已被多次回答 . 这本质上是一个“HTTP请求环境”辩论,而不是“应用程序”辩论 .

    关于roll-your-own-login问题(应用程序)似乎存在一个问题 .

    在这种情况下,除非您使用HTTP Auth vs登录页面(不依赖于设置HTTP Auth),否则仅仅登录不足以发送401或403 . 听起来您可能正在寻找“201 Created”,其中存在自己的滚动登录屏幕(而不是请求的资源),用于应用程序级别的文件访问 . 这说:

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

相关问题