在我的ASP.Net MVC应用程序中,如果用户在ajax调用期间注销或Session超时,则会将登录页面作为html返回到调用javascript ajax调用。这会导致客户端出错,因为它无法解析html。
我想覆盖handleunauthorizedrequest
属性上的authorize
,但即使在覆盖它之后,调试时也不会遇到此问题,但仍会返回登录页面。
如果请求是ajax请求且请求未经授权,我的目标是返回 401 状态代码。
这个问题的解决方案是什么,我仍然无法理解为什么handleunauthorizedrequest
没有被击中,是不是被覆盖了?
答案 0 :(得分:0)
以下情况应该有效。
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response;
if (request.IsAjaxRequest())
{
response.StatusCode = 401;
filterContext.Result = new EmptyResult();
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
然后在控制器或操作中使用过滤器
//instead of Authorize
[CustomAuthorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
在客户端添加ajaxError
事件的挂钩并检查状态代码401
。
$(function(){
$(document).ajaxError(function (e, xhr, opts) {
if (401 == xhr.status) {
//do whatever you like
//return document.location = document.location;
}
});
});
希望这会有所帮助。
答案 1 :(得分:0)
默认AuthorizeAttribute不处理AjaxRequest。您需要编写自己的实现。我在下面给出了一个示例实现,您可以根据需要进行自定义。
我在homecontroller中添加了一个动作来返回一个JsonResult并应用了默认的[Authorize]属性。
[Authorize]
public ActionResult SayHello()
{
object result=new {status="200",res="Hello"};
return Json(result, JsonRequestBehavior.AllowGet);
}
在视图中,我添加了一个简单的ajax事件来调用动作并将res显示为警告。
<h3>
<a id="anchorSayHello">Say Hello</a>
</h3>
@section Scripts{
<script>
$('#anchorSayHello').click(function () {
$.ajax('/Home/SayHello', {
success: function(data) {
var str = data.res;
alert(str);
}
});
return false;
});
</script>
}
因为,你已经告诉它将以未授权方式返回html响应。
现在,让我们实现自定义Authorize attribtue并应用于操作
public class TestAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
object res = new { status = "404", redirect = "/Account/Login" };
filterContext.Result = new JsonResult() { Data = res, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
return;
}
base.HandleUnauthorizedRequest(filterContext);
}
}
现在让我们将Javascript修改为,
$('#anchorSayHello').click(function () {
$.ajax('/Home/SayHello', {
success: function (data) {
if (data.status === '200') {
var str = data.res;
alert(str);
} else {
window.location = data.redirect;
}
}
});
return false;
});
现在它应该按预期工作,对于ajax请求,它也会重定向到登录页面。
答案 2 :(得分:0)
jquery中的jqXhr对象ajax有一个state属性,可以这样访问:
jqXhr.state()
如果state属性的值被“拒绝”,则表示没有返回json结果,并且您的调用被拒绝。
我使用此属性的值来确定会话是否已超时,并且我能够优雅地重定向到登录页面。
答案 3 :(得分:0)
从.NET 4.5开始,正确的答案是将HttpResponse[Base].SuppressFormsAuthenticationRedirect
设置为true:
if (!httpContext.Request.IsAuthenticated)
{
if (httpContext.Request.IsAjaxRequest())
{
httpContext.Response.SuppressFormsAuthenticationRedirect = true;
}
return new HttpUnauthorizedResult();
}