ajax请求中的未经授权的结果

Posted

技术标签:

【中文标题】ajax请求中的未经授权的结果【英文标题】:Unauthorized result in ajax requests 【发布时间】: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(); 【参考方案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();

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

【讨论】:

以上是关于ajax请求中的未经授权的结果的主要内容,如果未能解决你的问题,请参考以下文章

试图从 ajax 请求构建 http 适配器

MS 翻译请求未经授权

jquery $.ajax 在 Chrome 或 Firefox 中调用会导致 401 未经授权的响应,但在 IE 中有效

Web API2 使用默认Identity

向 web api 发送 ajax 请求时出现 401 Unauthorized

跨域 ajax 请求中的预检标头未解决授权标头