自定义授权属性 returns 403 页面而不是 Json 对象

Custom Authorization Attribute returns 403 page instead of Json Object

我创建了一个自定义授权属性,并将其应用于多个控制器。我现在发现我需要处理 Ajax 请求并优雅地重定向。

Ronnie's answer 这里看起来正是我所需要的,但是我只能得到一个通用的 403 forbidden html 页面而不是 JSON 对象。

SsoAuthorizeAttribute:

public class SsoAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        if (filterContext.HttpContext.Request.IsAjaxRequest()) {
            var urlHelper = new UrlHelper(filterContext.RequestContext);
            filterContext.HttpContext.Response.StatusCode = 403;
            filterContext.Result = new JsonResult {
                Data = new {
                    Error = "NotAuthorized",
                    SingleSignOn = Site.SSOUrl
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
            filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
        } else {
            filterContext.Result = new RedirectResult(Site.SSOUrl, false);
        }
    }

    public override void OnAuthorization(AuthorizationContext filterContext) {
        if (true) {
                HandleUnauthorizedRequest(filterContext);
            }
        }
    }
}

Javascript:

$(function () {
    $(document).ajaxError(function (e, xhr) {
        if (xhr.status == 403) {
            //xhr.responseText always contains a generic 403 page instead of the JSON object
            var response = $.parseJSON(xhr.responseText);
            window.location = response.LogOnUrl;
        }
    });
});

如果我将状态代码更改为 200:

filterContext.HttpContext.Response.StatusCode = 200;

一切如我所愿。

如何覆盖我遇到的行为,以便我可以 return 具有 403 状态的 JSON 对象?

post 中描述的行为是这部分 Web 配置的结果:

<system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="404" />
      <error statusCode="404" path="~/Error/NotFound" responseMode="ExecuteURL" />
      <remove statusCode="500" />
      <error statusCode="500" path="~/Error" responseMode="ExecuteURL" />
    </httpErrors>
</system.webServer>

该部分的存在启用了通用 403 页面的自动服务(可能是因为它具有 403 的默认路径和模式,即使您没有指定)。

更新 Web.config 以包含 403 也没有解决问题。该更改导致抛出 404 而不是 403(不知道为什么会这样)。

web.config 中存在自定义错误,替换

filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

终于解决了问题,允许 403 return Json。

工作代码:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
    if (filterContext.HttpContext.Request.IsAjaxRequest()) {
        var urlHelper = new UrlHelper(filterContext.RequestContext);
        filterContext.HttpContext.Response.StatusCode = 403;
        filterContext.Result = new JsonResult {
            Data = new {
                Error = "NotAuthorized",
                SingleSignOn = Site.SSOUrl
            },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    } else {
        filterContext.Result = new RedirectResult(Site.SSOUrl, false);
    }
}

感谢@CodeFuller 为我指明了正确的方向。