【问题标题】:MVC4 Forms Authentication + AJAX actionMVC4 表单身份验证 + AJAX 操作
【发布时间】:2013-11-15 15:29:53
【问题描述】:

在我的 ASP.NET MVC4 应用程序中,我使用了表单身份验证。应用程序中的一个视图需要通过 jQuery post() 调用获取一些字符串数据。我写了一个返回字符串的动作。在表单身份验证票到期之前一切正常。过期后,对字符串操作的 AJAX 调用会产生以下结果:

  • 动作中的代码没有被执行
  • 该操作返回 HTTP 200 而不是 401
  • 该操作将登录视图的 HTML 作为字符串返回
  • 因为返回了 200 状态而不是 401,所以控件以 jqXHR.done() 而不是 jqXHR.fail() 结束

这是预期的行为吗?我可以做些什么来使操作返回 401 吗?或者我应该做些什么来处理这个问题?

【问题讨论】:

    标签: c# asp.net-mvc-4 forms-authentication


    【解决方案1】:

    将代码放入 Application_EndRequest() 对我不起作用。以下是我的情况:

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

    【讨论】:

    • 这是迄今为止最干净的解决方案。我使用这个 sn-p 来解决我最初归咎于 ServiceStack.NET 的相同问题。希望我在 2 小时前找到这个!
    【解决方案2】:

    是的,这是预期的行为。

    在 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;
        }
    }
    

    或者你可以看看这个问题和答案:Forms authentication: disable redirect to the login page 并选择一个适合你的方法来返回 401。

    【讨论】:

    • 感谢您的回答。从我检查的内容来看,字符串操作中没有任何代码被执行。那我应该在哪里插入这行代码HttpResponse.SuppressFormsAuthenticationRedirect = true
    • 在 Application_EndRequest() 中,如果您将其添加到 global.asax,它将被自动调用。
    • 或者你当然可以创建一个 ActionFilterAttribute:asp.net/mvc/tutorials/older-versions/controllers-and-routing/…
    • 酷我看到编辑非常感谢。我认为 Application_EndRequest 方法要简单得多。
    • 欢迎您,就像我在之前的评论中提到的那样,您可能希望将代码包装在 ActionFilterAttribute 中,以便轻松控制您想要什么类型的响应 401/302。你可以用这个属性装饰一个类,然后把它留给另一个类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多