jquery – 返回部分视图的控制器操作会在授权失败时插入登录页面

我有一个看法,使用jQuery从控制器动作加载部分视图。控制器操作使用Authorize属性进行装饰,并且如果用户已经超时,当该操作被称为被重定向到正确的logon页面的整数时,logon页面将插入到部分视图将被删除的视图中。

还有另一篇文章here描述了一个使用jQuery的解决方案,但不幸的是它不包含任何代码示例,这是我需要的,因为我不太熟悉jQuery(和新的Web开发),我需要解决这个问题我会尽快。

所有我想要做的是将用户重定向到正确的logon页面,这对我来说听起来很直接,但到目前为止似乎不是这样。如果jQuery是要走的路,有人可以发布一个代码示例,这真的会帮助我。

谢谢。

解决方法

解决方法1,返回响应指示错误

Pro ASP.NET MVC 2 Framework为此提供了一个解决方

If an Ajax request is
denied authorization,then usually
you don’t want to return an HTTP
redirection to the login page,because
your client-side code is not
expecting that and may do something
unwanted such as injecting the entire
login page into the middle of
whatever page the user is on. Instead,
you’ll want to send back a more useful
signal to the client-side code,
perhaps in JSON format,to explain
that the request was not authorized.
You could implement this as follows:

public class EnhancedAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext context) 
    { 
        if (context.HttpContext.Request.IsAjaxRequest()) { 
            UrlHelper urlHelper = new UrlHelper(context.RequestContext); 
            context.Result = new JsonResult { 
                Data = new { 
                    Error = "NotAuthorized",logonUrl = urlHelper.Action("logon","Account") 
                },JsonRequestBehavior = JsonRequestBehavior.AllowGet 
            }; 
        } 
        else 
            base.HandleUnauthorizedRequest(context); 
    } 
}

然后,您可以从控制器返回一个JSON对象{‘Error’:’NotAuthorized’,’logonUrl’:’…’},然后您可以使用它来重定向用户

如果您期待HTML,则可以返回一个简单的字符串,例如NotAuthorized:< your_url>并检查响应是否匹配此模式。

解决方案2,返回和处理401未知状态码

由于这必须检查每个ajax请求的成功回调,这是相当乏味的。能够在全球范围内抓住这个案件将是件好事。最好的解决方案是从服务器返回401未经授权的状态代码,并使用jQuery的.ajaxError来捕获它,但是这在IIS / ASP.NET上是有问题的,因为如果响应有这样的话,它将致命的重定向登录页面的StatusCode。只要< authentication>标签存在于web.config中,如果您不做任何事情,此重定向将发生在[1]

所以我们来做一些事情。 This哈奇的方式似乎很好。在你的global.asax.cs

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302 && Context.Request.RequestContext.HttpContext.Request.IsAjaxRequest())
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

(如果有人知道有更好的方法返回401状态代码,我很乐意听到。)

通过这样做,当您的请求是ajax请求时,您将阻止重定向登录页面的默认行为。因此,您可以使用默认的AuthorizeAttribute,因为Application_EndRequest负责其余的。

现在,在jQuery代码中,我们将使用.ajaxError函数来捕获错误。这是一个全局的ajax事件处理程序,这意味着它将拦截任何ajax调用所产生的每个错误。它可以附加到任何元素 – 在我的例子中,我刚刚选择了身体,因为它始终存在

$("body").ajaxError(function(event,XMLHttpRequest,ajaxOptions,thrownError) {
    if (XMLHttpRequest.status == 401) {
        alert("unauthorized");
    }
});

这样你就可以将重定向逻辑集中在一个地方,而不必检查每一个死亡的ajax请求成功回调

解决方案3,返回自定义标题

This answer提供了一个替代解决方案。它使用相同类型的全局事件处理程序,但跳过黑客位。如果您未通过身份验证,并且请求是ajax请求,并在每个.ajaxComplete上检查此标题,则会向页面添加自定义页眉。请注意,链接答案中提供的方法不安全,因为它将返回原始视图有可能敏感的内容,并依靠javascript来重定向用户远离它。有了一些修改,它是非常好的,因为它不需要任何黑客,逻辑可以集中到一个回调函数。唯一的缺点就是我看不到它使用语义正确的状态代码回复,因为它实际上不是200 OK,因为你是401未经授权

我们可以将它烘焙成另一个自定义的EnhancedAuthorizationAttribute

public class EnhancedAuthorizeAttribute : AuthorizeAttribute
{
        protected override void HandleUnauthorizedRequest(AuthorizationContext context)
        {
            if (context.HttpContext.Request.IsAjaxRequest()) 
            {
                context.HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
                context.Result = new EmptyResult();
            }
            else
            {
                base.HandleUnauthorizedRequest(context);
            }
        }
    }
}

现在,每次ajax请求完成时,都会检查这个头文件

$('body').ajaxComplete(function(event,request,settings){
    if (request.getResponseHeader('REQUIRES_AUTH') === '1'){
        alert("unauthorized");
    };
});

相关文章

jQuery插件的种类 1、封装对象方法 这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进...
扩展jQuery插件和方法的作用是非常强大的,它可以节省大量开发时间。 入门 编写一个jQuery插件开始于给...
最近项目中需要实现3D图片层叠旋转木马切换的效果,于是用到了jquery.roundabout.js。 兼容性如图: ht...
一、什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异...
AMD 模块 AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一...