MVC4表单身份验证+ AJAX操作

3
在我的ASP.NET MVC4应用程序中,我使用表单身份验证。该应用程序中的一个视图需要通过jQuery的post()调用获取一些字符串数据。我编写了一个返回字符串的操作。一切都很好,直到表单身份验证票证过期。过期后,对字符串操作的AJAX调用会导致以下结果:
  • 操作内部的代码不被执行
  • 该操作返回HTTP 200而不是401
  • 该操作将登录视图的HTML作为字符串返回
  • 由于返回了200状态而不是401,所以控件最终进入jqXHR.done()中而不是jqXHR.fail()
这是否是预期行为?我能否做些什么使操作返回401?或者还有其他事情我应该注意处理?
2个回答

5

在Application_EndRequest()中放置代码对我没用。以下是在我的情况下有效的方法:

    protected void Application_BeginRequest()
    {
        HttpRequestBase request = new HttpRequestWrapper(Context.Request);
        if (request.IsAjaxRequest())
        {
            Context.Response.SuppressFormsAuthenticationRedirect = true;
        }
    }

这绝对是最干净的解决方案。我用这段代码片段解决了一个完全相同的问题,最初还怪罪于ServiceStack.NET。真希望我2小时前就找到了这个! - Tyler Forsythe

0

是的,这是预期的行为。

在Asp.Net 4.5中,HttpResponse.SuppressFormsAuthenticationRedirect Property已被添加。但默认行为仍然是重定向到登录页面。来自MSDN:

默认情况下,表单身份验证将HTTP 401状态代码转换为302,以便重定向到登录页面。对于某些类别的错误,例如身份验证成功但授权失败或当前请求是AJAX或Web服务请求时,这是不合适的。此属性提供了一种方法来抑制重定向行为并将原始状态代码发送到客户端。

您可以使用此属性或尝试this answer中的以下解决方法:

protected void Application_EndRequest()
{
     if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

或者您可以查看这个问题和答案:表单身份验证:禁用重定向到登录页面,并选择适合您的方法返回401。


谢谢您的回答。根据我检查,字符串“action”中没有执行任何代码。那么我应该在哪里插入这一行代码“HttpResponse.SuppressFormsAuthenticationRedirect = true”? - joym8
如果您将Application_EndRequest()添加到global.asax中,它将自动调用。 - Jos Vinke
当然,您也可以创建一个ActionFilterAttribute:http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs - Jos Vinke
酷,我看到了编辑,非常感谢。我认为使用Application_EndRequest方法更简单。 - joym8
作为补充,欢迎您。正如我在之前的评论中提到的那样,您可能希望将代码包装在ActionFilterAttribute中,以便轻松控制何时返回401/302响应。您可以使用该属性装饰一个类,并从另一个类中排除它。 - Jos Vinke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接