如何在AJAX中使用自定义AuthorizeAttribute

时间:2013-08-09 12:13:08

标签: c# javascript jquery asp.net-mvc

在朋友的帮助下,我设法从这个主题找到了我的问题的解决方案:Reusable way to allow an account to be used by a single person at a time

我有一个SingleLogin类,它继承自AuthorizeAttribute并实现一个自定义AuthorizeCore方法,以便重新使用我的单一登录代码:

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);

        if (isAuthorized)
        {
            int userId = (int)WebSecurity.CurrentUserId;
            using (var db = new UsersContext())
            {
                if ((httpContext.Session.SessionID != db.getSessionId(userId))
                    || db.getSessionId(userId) == null)
                {
                    WebSecurity.Logout();
                    isAuthorized = false;
                    httpContext.Response.Redirect("/Home/Index");
                }
            }
        }

        return isAuthorized;
    }

除了我的JsonResult动作之外,一切正常:

    [HttpPost]
    public JsonResult MessageSave(string message)
    {
        bool messageSaved = false;
        int userId = (int)WebSecurity.CurrentUserId;
        message = HttpUtility.HtmlEncode(message);

        // Model method - adding chat log - db
        db.addChatLog(message, userId);
        messageSaved = true;

        return Json(new { messageSaved = messageSaved });
    }

此方法由Ajax POST调用触发,您可以在下面的代码示例中看到。只是基本的POST。

编辑3 请检查这些图像:http://imgur.com/a/Cjael ..我想POST确实会触发,但是当我尝试在$ .ajax之前测试它时,我不知道为什么我的警报不起作用......正如你在回复中所看到的那样获取Home / Index页面,但我没有立即重定向到home / index(文本保留在textBox内部,页面只是等待..),我必须再次按下输入才能重定向..非常奇怪。

EDIT2 看起来即使我退出后我甚至无法访问我的jQuery。我在.js文件中添加了一些警报。

我有一个单独的.js文件,然后将其作为<script src="~/Scripts/custom/homeChat.js"></script>放入我的视图中。我通过HTML5数据将View中的Razor值传递给我的JS文件 - 。

我的textBox元素#txtMsg触发了我的jQuery事件,因此当我退出时它可能不再识别我的textBox元素,并且不会触发我的jQuery事件?

在视图中触发.js的元素是: @Html.TextBox("txtMsg")

JS:

$("#txtMsg").keypress(function (e) {

        //when enter
        if (e.which == 13) {
            alert("ALERT DOESNT TRIGGER");

                $.ajax({
                    type: "POST",
                    url: url,
                    data: JSON.stringify({ message: input }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {
                        if (data.messageSaved) {
                            $("#txtMsg").val("");
                        }
                        else {
                            window.location.href = urlhome;
                        }
                    }
                });
            }
        }
    });

所以如果你甚至不能参加你的活动,你怎么能知道出了什么问题?我有这个˙HandleUnauthorizedRequest但是你需要你可以进入你的jQuery事件(在我的情况下,在上面的js代码中 .keypress ),如果我理解的话,这可以工作。

编辑:补充说明

让我解释一下这个场景。如果我使用我的用户名“john”从Firefox登录,再次使用chrome的用户名“john”,我在Firefox中执行的下一步操作,它会将我注销并将我重定向到Home / Index,因为其他人在Chrome中进行了新的登录

没关系。由于您不再登录,如果您的操作是正常的ActionResult并返回视图,您将被正常重定向到您的主页/索引。

我遇到的问题是,我在页面中有一些其他功能,它使用Ajax POST,并且由于您已注销,因此无法对该JsonResult操作进行POST,因此您甚至无法收到错误回调,它将您重定向到Home / Index。我在我的JS中添加了一些警报,但没有警报触发这是正常的,因为无论如何我都不允许在该页面上。如果我想要我的onEnter文本框将我重定向到Home / Index我必须按两次输入。这一切都可以做到吗?

我对这个AJAX问题的最佳方法感兴趣。我不知道应该如何调用它,但是当我从上一个主题中读到它时,它被称为“处理AJAX超时”?

非常感谢。

2 个答案:

答案 0 :(得分:2)

如果理解正确,您需要处理未经授权的ajax请求

在这种情况下,您可以覆盖属性中的HandleUnauthorizedRequest方法:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (filterContext.HttpContext.Request.IsAjaxRequest()) 
    {
        filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
        filterContext.Result = new JsonResult();
    }
    else
    {
        filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
    }
}

答案 1 :(得分:1)

您可以通过这种方式处理AJAX请求上的错误

$.ajax({
    type: "POST",
    url: url,
    data: JSON.stringify({ message: input }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        if (data.messageSaved) {
            $("#txtMsg").val("");
        }
        else {
            window.location.href = urlhome;
        }
    },
    error: function(xhr, status, error) {
        // TODO: may be check error or status or xhr.statusCode()
        window.location.href = urlhome;
    }
});

jQuery $.ajax() docs