【问题标题】:POSTing Ajax form using [Authorize] attribute after the user is logged out ASP.NET用户注销后使用 [Authorize] 属性发布 Ajax 表单 ASP.NET
【发布时间】:2016-09-02 22:45:56
【问题描述】:

简介

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

我在模态窗口中有一个 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" });
    }
}

如您所见,如果需要,我会返回一个带有 success 属性和 error 的 Json 对象。

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

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

如果不成功并返回错误,则会在错误div 中填充我发回的错误消息。听起来很简单?..


场景

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

如果他们空闲/停留在页面上的时间超过了分配的时间,那么令牌就会用完。

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

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


想象一下

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

用户已在页面上停留了 15 分钟,他们的令牌现已过期。

他们单击按钮执行[Authorize]d 操作...

Action方法没有执行,WebApp返回一个重定向到登录页面。

但是通过这个 Ajax 调用返回的是整个登录页面。并且看到没有success,回调函数接收重定向,这会挤压登录页面 - 全部进入这个小tiny div

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


问题

很明显,WebApp 实现了[Authorize] 属性,并且用户已注销。

我无法在 Action 中设置任何断点,因为 [Authorize] 接管并自动重定向。

所以,我要问的是:

如何绕过/克服/解决这个问题,首先触发 [Authorize] 并且不执行 Action 代码块?

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

【问题讨论】:

标签: c# asp.net ajax authorize-attribute authorize


【解决方案1】:

您可以删除 [Authorize] 属性,检查控制器方法中的授权 (if (User.Identity.IsAuthenticated)),如果用户未获得授权,则向客户端返回适当的错误。

【讨论】:

  • 谢谢@Joe! - 我敢肯定,我确实考虑过这一点。使用这种方式有什么影响吗?还是[Authorize] 使用相同的检查,只是更高;因此没有达到方法?当我回到办公室时,我会尝试一下:)
  • 辛苦了!非常感谢@Joe。你可以告诉我吗;这与[Authorize] 在更高的反射中使用的检查基本相同吗?我不认为有任何影响,是吗?
  • @GeoffJames - 是的,这是同一张支票,并没有真正的影响。
  • 太棒了。再次感谢! :)
【解决方案2】:

你可以创建一个自定义属性,这样你就可以将它们重定向到登录控制器,无论你想要做什么。我所做的就是将它们返回到我的 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);
            }
        }



    }

}

检查这个答案redirects to login if unauthorized ajax call

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 2020-08-15
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    相关资源
    最近更新 更多