6

在我的 MVC3 项目中,我有一个带有 [Authorize] 属性的控制器。我有一个没有 ajax 的表单提交,如果他/她没有登录,它会将用户(如预期)重定向到登录屏幕。

但是,现在我有一个使用 jquery ajax 提交的表单,我该如何做同样的事情?将用户重定向到登录屏幕,如果他/她没有被授权?成功登录后,用户应该被重定向到初始操作。

控制器

[Authorize]
[ValidateInput(false)] 
public JsonResult SubmitChatMessage(string message)
        {
            if (!string.IsNullOrEmpty(message))
            {
                // Do stuff
            }

            // Return all chat messages
            return GetChatMessages();
        }

客户端 JQUERY

$(document).ready(function () {
    $("form[action$='SubmitChatMessage']").submit(function (event) {
        $.ajax({
            url: $(this).attr("action"),
            type: "post",
            dataType: "json",
            data: $(this).serialize(),
            success: function (response) {
                // do stuff
            }
        });
        return false; 
    });
});

我可以从 firebug 控制台窗口看到,服务器返回:

GET http://domain/Account/LogOn?ReturnUrl=%2fProductDetails%2fSubmitChatMessage

期待您的帮助!

更新了可能的解决方案

4

2 回答 2

6

是的,这是我一直讨厌ASP.NET 中的表单身份验证的一件事——根本不适合 AJAX 身份验证。将处理 401 的 IIS 添加到混合中,这可能会很痛苦。

有几种方法可以做到这一点,它们都不是特别“干净”的。

这些包括:

  1. 在控制器中设置一个 ViewBag 标志,对应于Request.IsAuthenticated,然后如果未通过身份验证,则将提交按钮单击事件重写到登录页面。

  2. 让您的 AJAX 操作返回JsonResult,它是“代码”的属性。代码 0 可能是成功的,1 可能是未经身份验证的,2 可能是其他一些数据问题,等等。然后在complete $.ajax回调中检查该代码并重定向到登录页面。

  3. 检查$.ajax jqXHR响应对象的状态码403,并重定向到登录页面。

  4. 为您的提交按钮编写一个自定义 HTML 帮助程序,根据身份验证状态呈现常规提交按钮或转到登录页面的锚标记。

  5. 编写一个自定义授权属性来检查是否Request.IsAjaxRequest(),并返回一个自定义 JSON 对象,而不是重定向到登录页面的默认行为(AJAX 请求不会发生这种情况)。

于 2011-08-01T23:47:53.857 回答
0

老实说,这有点痛苦。在我看来,更重要的是,如果您使用的是联合身份,例如 Windows Identity Foundation 和/或 Azure AppFabric 访问控制服务。

您的 Ajax 调用无法处理重定向。

我的解决方案/建议不是用 [Authorize] 标记您的 Ajax 调用控制器操作方法,而是依赖于您从具有 [Authorize] 的控制器操作(通常是控制器为显示视图而调用的操作方法)。您知道除非用户经过身份验证(并且会话尚未超时),否则该值不能进入会话状态。如果此值不存在,则调用您的 Ajax 方法失败,返回一个特定的 JSON 结果,您可以在客户端代码中优雅地处理该结果。

在 Ajax 控制器方法上使用 [Authorize] 会导致奇怪的、通常是隐藏的错误(例如更新消失)。

于 2011-07-31T18:03:44.807 回答