自定义授权属性 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 为我指明了正确的方向。
我创建了一个自定义授权属性,并将其应用于多个控制器。我现在发现我需要处理 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 为我指明了正确的方向。