用户注销后使用 [Authorize] 属性发布 Ajax 表单 ASP.NET

问题描述 投票:0回答:3

简介

我正在使用 C# 中的 ASP.NET MVC 为客户端构建 Web 应用程序。

我在模式窗口中有一个 Ajax 表单,当用户单击按钮时会提交该表单。

用户必须登录才能进入此特定页面并执行此特定操作 - 因此我使用

[Authorize]
属性来执行必要的控制器操作。

假设表单要发布的控制器操作如下所示(伪代码,只是一个示例)

[Authorize]
public ActionResult DoAjaxThings(string field, string anotherfield)
{
    // ... do things
    if (success)
    {
        return Json(new { success = true });
    }
    else
    {
        return Json(new { success = false, error = "Something went wrong" });
    }
}

如您所见,我返回一个 Json 对象,其中包含

success
属性和
error
(如果需要)。

然后由页面中的回调方法处理,然后显示旋转器、独角兽和其他魔法。

如果成功,模式将关闭并显示“成功”消息。

如果不成功并返回错误,则我发回的错误消息会填充错误

div
。听起来相当简单?..


场景

假设用户的会话令牌仅持续 15 分钟 - 并且正在滑动(每个新请求都会重置它(对于问题不一定至关重要))。他们没有使用“记住我”选项。

如果他们闲置/坐在页面上的时间超过了指定的时间,那么令牌就会耗尽。

显然,此时他们的会话令牌已过期,他们将需要重新登录。

导航到

[Authorize]
控制器操作时会发生常见行为:使用
ReturnUrl=xyz
查询字符串将用户带回登录页面。


想象一下这个

那么,回到模态的 Ajax 表单。

用户已在页面上停留 15 分钟,其令牌现已过期。

他们单击按钮来执行

[Authorize]
d 操作...

Action 方法未执行,WebApp 返回重定向到登录页面。

但是通过此 Ajax 调用返回的是整个登录页面。由于没有

success
,回调函数收到重定向,这会压缩登录页面 - 全部变成这个小tiny
div

你不需要我告诉你这看起来很可怕。


问题

可以清楚地看到WebApp实现了

[Authorize]
属性并且用户已注销。

我无法在操作中命中断点,因为

[Authorize]
会自动接管并重定向。

所以,我要问的是:

如何绕过/克服/解决这个问题,首先触发

[Authorize]
并且操作代码块不被执行?

一如既往地感谢您的善意建议、答案和一般指导。

c# asp.net ajax authorize-attribute authorize
3个回答
3
投票

您可以删除 [Authorize] 属性,检查控制器方法中的授权 (

if (User.Identity.IsAuthenticated)
),如果用户未获得授权,则向客户端返回适当的错误。


0
投票

您可以创建一个自定义属性,这样您就可以将它们重定向到登录控制器,无论您想要做什么。我所做的是将它们返回到我的 accessdenied 操作。当 ajax onerror 发生时通过 ajax 重定向。

  public class ApiAuthAttribute : AuthorizeAttribute
  {
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {

        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var urlHelper = new UrlHelper(filterContext.RequestContext);
                filterContext.HttpContext.Response.StatusCode = 403;
                filterContext.Result = new JsonResult
                {
                    Data = new
                    {
                        Error = "NotAuthorized",
                        LogOnUrl = urlHelper.Action("AccessDenied", "Login")
                    },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }



    }

}

检查此答案如果未经授权的ajax调用则重定向到登录


0
投票

如果您在网络选项卡中进行观察,您将看到,尽管状态代码为

200
,但服务器仍以
X-Responded-JSON
进行响应,可以对其进行解析以获取实际的服务器状态代码响应,即
401
在这种情况下,您可以在
Authorize
调用中处理来自
AJAX
属性的响应,如下所示在
.cshtml
查看文件中:

$.ajax({
    url: '@Url.Action("MyMethod", "MyController")',
    type: "POST",
    dataType: "html",
    data: myData,
    success: function (data, textStatus, xhr) {
        //For handling 401 with Authorize attribute on Controller
        if (xhr.getResponseHeader("X-Responded-JSON") != null && JSON.parse(xhr.getResponseHeader("X-Responded-JSON")).status == "401") {
            alert("Unauthorized access returned by Controller");
            //Will redirect to login page
            location.reload(true);
        }
        else {
            alert("Still Authorized");
        }
    },
    error: function (err) {
        alert("There was a technical error");
        console.log(err)
    },
});
© www.soinside.com 2019 - 2024. All rights reserved.