【问题标题】:Unauthorized result in ajax requestsajax请求中的未经授权的结果
【发布时间】:2012-03-25 10:05:46
【问题描述】:

我有许多 ajax 操作(使用 JQuery.ajax 实现)的应用程序,它返回 JSON ot html。其中一些应该只有授权用户才能访问,我用[Authorize] 属性装饰了它们。对于非 ajax 操作,如果用户未经授权 - 系统会将他重定向到登录页面(在 web.config 中配置)。

但这不适用于 ajax 操作,因为如果用户被授权 - 他加载页面,在该 cookie 过期并且他未被授权之后,而不是 html 块,应该替换旧的,他得到我的登录页面块内.

我知道我可以手动解决这个问题,例如删除 [Authorize] 属性,如果用户没有授权,则返回特殊的 json/empty html。但我不喜欢这个解决方案,因为我需要重写所有的动作和 ajax 函数。我想要全局解决方案,允许我不重写我的操作(可能是自定义授权属性,或一些 http 未经授权的结果自定义处理)。

如果请求是ajax,我想返回状态码,如果请求不是ajax,我想重定向到登录页面。

【问题讨论】:

  • "如果请求是 ajax,我想返回状态码,如果请求不是 ajax,我想重定向到登录页面。" -- 好像你已经概述了这个问题的解决方案,不是吗?
  • 此时您尝试过做什么?不管你走哪条路,都会涉及到一些重写。
  • 有时我是个白痴。尝试使用 Request.isAjaxRequest();

标签: jquery asp.net-mvc asp.net-mvc-3 http-status-code-401 unauthorized


【解决方案1】:

将 Application_EndRequest 处理程序添加到 global.asax.cs 中的代码,将任何 302 错误(重定向到登录页面)修改为 AJAX 请求的 401(未经授权)错误。这将允许您简单地将控制器操作保持原样并通过客户端处理重定向(如果他们当前没有,您实际上只能让用户再次登录)。

protected void Application_EndRequest()
{
    // Any AJAX request that ends in a redirect should get mapped to an unauthorized request
    // since it should only happen when the request is not authorized and gets automatically
    // redirected to the login page.
    var context = new HttpContextWrapper( Context );
    if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
    {
        context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

然后在您的 _Layout.cshtml 文件中添加一个全局 AJAX 错误处理程序,当它收到 401 响应时重定向到您的登录操作。

<script type="text/javascript">
    $(function () {
        $(document).ajaxError(function (e, xhr, settings) {
            if (xhr.status == 401) {
                location = '@Url.Action( "login", "account" )';
            }
        });
    });
</script>

您可能还想尝试 Phil Haack 的博客Prevent Forms Authentication Login Page Redirect When You Don’t Want It中列出的一些技术

【讨论】:

  • if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest() && context.Response.RedirectLocation.StartsWith("/Account/Login")) 我建议在条件,否则它可能会捕获一些其他重定向并返回未经授权的......这是不希望的......
【解决方案2】:

您不必重写所有操作,只需创建一个自定义过滤器来替换内置的Authorize 过滤器。

其他人已经这样做了

asp.net mvc [handleerror] [authorize] with JsonResult?

【讨论】:

    【解决方案3】:

    您可以检查 Request.IsAjaxRequest() 扩展方法,如果为真,则采取特定操作。

    【讨论】:

      【解决方案4】:

      如果 Request.IsAjaxRequest() 为真,您在 AccountController(或任何您拥有它的地方)中的 LogOn 操作可能会返回不同的结果。

      这意味着,如果对授权操作的 AJAX 调用未获得授权,您应该能够通过 LogOn 操作返回适当的响应..

      例如

      public ActionResult LogOn()
      {
          if (Request.IsAjaxRequest())
          {
              // do appropriate response for ajax call here
          }
      
          return View();
      }
      

      那么,你应该不需要进行重大的重写

      【讨论】:

        猜你喜欢
        • 2012-08-17
        • 1970-01-01
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-04
        • 1970-01-01
        相关资源
        最近更新 更多