未经授权的AJAX请求返回状态码200而不是401

问题描述:

在MVC 5中,我重写HandleUnauthorizedRequest()并检查请求是否来自AJAX。未经授权的AJAX请求返回状态码200而不是401

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

问题:是否需要手动更改filterContext中的状态码HandleUnauthorizedRequest()

未经授权的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); 
    } 
} 

全球ajaxComplete注册

$(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 
    } 
}); 

是 - 我没有检查这一点,但尝试添加线指示指定代码401不经过过滤,以你想要的结果(我怀疑这我。原因可能会拦截身份代码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); 
    } 
} 
+0

其实这就是我tryed(有和没有两个额外的行太)filterContext.HttpContext.Response.StatusCode = 401; filterContext.HttpContext.Response.End(); filterContext.HttpContext.Response.Close(); 但没有运气,状态码仍然“200”即时通讯如此混乱。我会再次检查一次,只是为了你。 – radbyx

+0

我还是得到了“200”: xhr.status:“200”和xhr.statusCode()。status:“200” – radbyx

+1

嗯。这段代码应该封装成如下形式:public class CustomAuthorizeAttribute:AuthorizeAttribute {} - 然后您必须确保您的操作是通过[CustomAuthorize]进行“装饰”的 - 在基础控制器,控制器或单个操作上 - if你不添加这个,自定义代码不会踢。你有没有检查过你的行为是用同等的[]来装饰的? – RickL