被禁止的页面是不是应该总是以 403 代码响应?

Posted

技术标签:

【中文标题】被禁止的页面是不是应该总是以 403 代码响应?【英文标题】:Should a forbidden page always respond with a 403 code?被禁止的页面是否应该总是以 403 代码响应? 【发布时间】:2014-10-22 10:54:53 【问题描述】:

我有一个 ColdFusion 网站,它根据登录用户的属性以编程方式处理 onrequeststart()Application.cfc 中的“禁止”/“未授权”请求。例如(仅供参考:SESSION.UseronSessionStart() 中初始化:

<cffunction name="onRequestStart" returnType="Boolean" output="false">
    <cfargument name="targetPage" type="string" required="true">

    <cfparam name="REQUEST.MinSecurityLevel" default="0" />
    <cfparam name="REQUEST.IsLoginRequired" default="false" />

    <cfif REQUEST.IsLoginRequired AND NOT SESSION.User.isLoggedIn()>
        <cfscript>
            SESSION.LoginMessage =
                "Your session has timed out. Please log in again.";
            SESSION.LastPageVisited =
                getPageContext().getRequest().getRequestURI();

            if (Len(Trim(getPageContext().getRequest().getQueryString())))
                SESSION.LastPageVisited =
                        SESSION.LastPageVisited
                    &   "?"
                    &   getPageContext().getRequest().getQueryString();
        </cfscript>

        <cflocation url="/user/login/" addtoken="false" />
    <cfelseif SESSION.User.getSecurityLevel() LT REQUEST.MinSecurityLevel>
        <cfheader statuscode="403" statustext="Forbidden" />
    </cfif>

    <cfreturn true />
</cffunction>

在 IIS(版本 7)中,我有一个错误页面设置,类型为“执行 URL”和我的自定义 403 页面路径。

我能够触发此操作,它会正确显示我的自定义 403 页面,但它会返回 HTTP 响应代码 200。

这不应该返回 403 吗?

【问题讨论】:

我对您的要求感到困惑。标题表明您在询问是否应针对特定情况返回 403 代码,但您的问题似乎指出了一个问题,即您试图发送回 403 代码但实际上返回了 200 代码。你能澄清一下吗?如果是后者,我会遇到与 ColdFusion 处理的 404 代码相同的问题。 您想在 cfheader 之后立即执行 cfabort 以停止所有未来的处理吗?我认为这可以保证您返回 403。 @RandyJohnson 添加 CFABORT 具有相同的结果。不过,谢谢。 @Miguel-F 我想我在问这两个问题 - 它是否应该总是返回 403(最佳实践),为什么我的应用程序不返回 403?我在 ColdFusion/IIS 中有一个针对 404 的解决方案: 1. 不要使用 onMissingTemplate()。 2. 将 IIS 设置为“始终检查文件是否存在”。 3. 将 404 的自定义错误页面设置为自定义 404 路径的执行 URL(我的是“/missing-template/index.cfm”,然后在该模板文件的顶部添加:。这对我来说非常有用,可以捕获所有 404 - CF 等。 查看您的代码,REQUEST.MinSecurityLevel 似乎始终为 0。SESSION.User.getSecurityLevel() 会返回负数吗? 【参考方案1】:

似乎我在上面对@Miguel-F 的回复中找到了解决方案。我只是模仿了处理 404 错误的部分操作:

/missing-template/index.cfm:

<cfheader statuscode="404" statustext="Not Found" />

/not-authorized/index.cfm:

<cfheader statuscode="403" statustext="Forbidden" />

我认为向 403 处理程序页面添加 403 标头会导致无限循环,但它工作正常。

我还添加了 onRequestStart() ,因为一旦触发 403 就不需要进一步处理:

<cfelseif SESSION.User.getSecurityLevel() LT REQUEST.MinSecurityLevel>
    <cfheader statuscode="403" statustext="Forbidden" />

    <cfreturn false />
</cfif>

【讨论】:

很高兴你让它工作了!要回答您的其他问题,对于需要用户身份验证的页面,我通常会返回 401 Unauthorized。从 w3.org 阅读这些描述 - 401 请求需要用户身份验证。响应必须包含一个 WWW-Authenticate 头字段,该字段包含适用于所请求资源的质询。客户端可以使用合适的授权头域重复请求。 403 服务器理解请求,但拒绝执行。授权将无济于事,不应重复请求。

以上是关于被禁止的页面是不是应该总是以 403 代码响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 403 禁止响应的 WebException?

Python请求响应403被禁止

尝试使用 YouTube 分析 API 检索指标时禁止出现 403

混合 200(正常)和 403(禁止)HTTP 响应

HTTP 错误 403.9 - 禁止访问:连接的用户过多

403 - 禁止访问: 访问被拒绝。您无权使用所提供的凭据查看此目录或页面。 怎么解决 ?