【问题标题】:Unauthorized AJAX requests returning statuscode 200 instead of 401未经授权的 AJAX 请求返回状态码 200 而不是 401
【发布时间】:2016-06-22 03:40:15
【问题描述】:

在 MVC 5 中,我覆盖 HandleUnauthorizedRequest() 并检查请求是否来自 AJAX。

我还注册了一个全局ajaxComplete,用于处理401个AJAX请求,但是在HandleUnauthorizedRequest()之后状态码还是200。

问题:我是否必须在函数HandleUnauthorizedRequest() 中手动更改filterContext 中的状态码?

检测到未经授权的 AJAX 请求

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (filterContext.HttpContext.Request.IsAjaxRequest())
    {
        // <-- in here
        filterContext.Result = new JsonResult
        {
            Data = new
            {
                returnUrl = "foo"
            },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
    else
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
}

全局ajax完成注册

$(document).ajaxComplete(function (e, xhr, settings) {
    console.log('xhr.status: "' + xhr.status +'"'); // 200 - i want 401
    if(xhr.status === 401) {
        window.location.replace(urlHelper.getUrlNotAuthorized());
    }
});

“在我找到使用 ajaxComplete 的解决方案之前,可以使用但被破解的解决方案。

它检查用户请求是否被授权。缺点是我每次提出请求时都必须检查isAuthorized()。这就是我想使用全局 ajaxComplete 的原因,所以我不会错过任何一个。”:

检查用户 AJAX 请求是否被授权

isAuthorized = function (result) {
    try {
        var obj = JSON && JSON.parse(result) || $.parseJSON(result);
        // Here, obj can still be a parsed JsonResult, from when getting GetDatatableRows(), so we also need to check on returnUrl which is distinct
        // obj will only contain returnUrl if the JSON was returned from Shield validation
        if (obj && obj.returnUrl) {
            window.location.replace(urlHelper.getUrlNotAuthorized() + '?returnUrl=' + encodeURIComponent(obj.returnUrl));
            return false;
        }
    } catch (e) {
    }
    return true;
};

AJAX 请求,其中结果是部分视图或 JSON

partialViewService.changePartialViewService(url, data)
.done(function (result) {
    if (isAuthorized(result)) {
        // use result
    }
});

【问题讨论】:

    标签: javascript ajax asp.net-mvc authentication asp.net-mvc-5


    【解决方案1】:

    是的 - 我没有检查这个,但尝试添加指示的行。指定代码 401 不会过滤到您想要的结果。 (我怀疑这是由于 Identity 截取代码 401 造成的):

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // Add this (code 401 does not work)
            filterContext.HttpContext.Response.StatusCode = 412;
            // <-- in here
            filterContext.Result = new JsonResult
            {
                Data = new
                {
                    returnUrl = "foo"
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
    

    【讨论】:

    • 实际上这就是我刚刚尝试过的(也有和没有额外的两行) filterContext.HttpContext.Response.StatusCode = 401; filterContext.HttpContext.Response.End(); filterContext.HttpContext.Response.Close();但是没有运气,状态码仍然是“200”,我很困惑。不过,我会再为您检查一次。
    • 我还是得到了 "200": xhr.status: "200" 和 xhr.statusCode().status: "200"
    • 嗯。这段代码应该封装在类似的东西中: public class CustomAuthorizeAttribute : AuthorizeAttribute { } - 然后你必须确保你的动作用 [CustomAuthorize] “装饰” - 在基本控制器、控制器或单个动作上 - 如果你不要添加这个,自定义代码不会启动。您是否检查过您的操作是否用等效的 [] 装饰?
    • 是的,我的所有控制器上都有“[ShieldAuthorize, ShieldWebUserCmpBu, ShieldWebUserRight]”。 “ShieldAuthorize”是我的“CustomAuthorizeAttribute”。我也覆盖了 AuthorizeCore:“ protected override bool AuthorizeCore(HttpContextBase httpContext) { var authorized = base.AuthorizeCore(httpContext); if (!authorized) { return false; // 用户没有被授权 => 不需要再进一步}返回真;}"
    • 感谢您帮助我。同时,我添加了一个工作但被破解的版本,它还没有使用 ajaxComplete。在这里,我可以询问“returnUrl”而不是状态码,但问题是我必须记住在每个地方都调用验证方法,而且有时肯定会失败。
    猜你喜欢
    • 2012-08-17
    • 2021-04-26
    • 2013-12-30
    • 1970-01-01
    • 2019-03-23
    • 2013-01-01
    • 1970-01-01
    • 2015-09-14
    • 2012-11-27
    相关资源
    最近更新 更多