20

对于我的网站,我希望遵循安全控制器(或操作)的行为

如果用户发出正常请求重定向到登录页面(我很容易做到)

如果请求是 Ajax 类型 Request.IsAjaxRequest()==true,返回状态码 401

我该如何为此创建过滤器?

4

6 回答 6

29
 public class MyCustomAuthorize : AuthorizeAttribute
{
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //if ajax request set status code and end Response
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.Response.StatusCode = 401;
                filterContext.HttpContext.Response.End();
            }

            base.HandleUnauthorizedRequest(filterContext);
        }
}

创建一个像上面这样的过滤器,如果请求是通过 ajax 发出的,它将为未经授权的请求返回状态代码 401。

如果您使用的是 jQuery,您可以执行以下操作

jQuery.ajax({
statusCode: {
    401: function() {
      alert('unauthrized');
    },

  /*other options*/
});
于 2011-08-09T20:05:46.710 回答
4

除了接受的答案之外,我还需要输入这行代码以防止 FormsAuthentication 重定向到登录页面。

filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

然后我删除了 filterContext.HttpContext.Response.End();

var unauthorizedResult = new JsonResult
{
    Data = new ErrorResult() {Success = 0, Error = "Forbidden"},
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
    // status code
    filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
    // return data
    filterContext.Result = unauthorizedResult;
    filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
}
于 2014-01-24T22:12:03.140 回答
1

您的问题不在于 AJAX 请求,您的问题是返回 HTTP 401 Unauthorized 响应,因为您使用表单身份验证。此响应代码告诉框架它应该使用 HTTP 302 响应将用户代理重定向到您的登录页面。这就是为什么设置“正常”请求重定向很容易的原因——它是自动完成的。
为了回答你的问题,我遇到了类似的问题,我最终得到的解决方案是不使用表单身份验证。我实现了一个自定义授权属性,改为手动处理这两种情况。我不确定这是否是最好的方法,但它确实有效。我对其他人对此解决方案的看法或存在哪些其他解决方案感兴趣。
幸运的是,您仍然可以使用FormsAuthentication类为您处理 cookie,但您必须从 Web.config 文件中删除表单身份验证配置。当用户登录时,FormsAuthentication.SetAuthCookie您通常会设置一个 cookie(您可能已经这样做了)。其次,在您的授权属性中,您从请求中获取 cookie 并使用FormsAuthentication.Decrypt它来解密它。如果它存在并且有效,您将HttpContext基于此 cookie 设置用户,因为表单身份验证将不再为您执行此操作。如果不是,您要么重定向到登录页面,要么返回 401,这取决于它是否是 AJAX 调用。

于 2011-08-09T07:38:37.890 回答
1

您可以使用ajaxonly来限制对 ajax actionresult 的访问

于 2011-08-09T09:02:49.840 回答
1

您可以只返回一个HttpUnauthorizedResult

注意:这可能会导致 MVC 框架将您返回到登录页面。

public ActionResult FailResult()
{
        return new HttpUnauthorizedResult();
}
于 2011-08-09T09:39:33.603 回答
0

一种简单的方法是在 SignIn 操作中进行检查

public ActionResult SignIn()
{
    if (Request.IsAjaxRequest())
    {
        // you could return a partial view that has this script instead
        return Content("<script>window.location = '" + Url.Action("SignIn", "Account") + "'</script>");
    }
   ...
   return View();
于 2016-11-28T10:44:51.667 回答