Я работаю в проекте MVC, где роли пользователя и разрешения для каждого из методов действий хранятся в базе данных. То, что я хочу достичь, - использовать функцию фильтра авторизации в mvc, переопределив AuthorizeAttribute. Таким образом, я могу зарегистрировать свой настраиваемый фильтр авторизации по всему миру.Изменение кода response.status для запросов ajax вызывает ошибку «Сервер не может установить статус после отправки HTTP-заголовков»
Вот что я пытаюсь сделать, следуя this method. Я следую this article для обработки запросов ajax.
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Custom permission checking logic
return false;//no permission for all methods-Just for testing
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
CheckIfUserIsAuthenticated(filterContext);}
}
private void CheckIfUserIsAuthenticated(AuthorizationContext filterContext)
{
// If Result is null, we’re OK: the user is authenticated and authorized.
if (filterContext.Result == null)
return;
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
var user = httpContext.User;
// If here, you’re getting an HTTP 401 status code. In particular,
// filterContext.Result is of HttpUnauthorizedResult type. Check Ajax here.
if (request.IsAjaxRequest())
{
if (user.Identity.IsAuthenticated == false)
response.StatusCode = (int)HttpStatusCode.Unauthorized;//401
else
response.StatusCode = (int)HttpStatusCode.Forbidden;//403
response.SuppressFormsAuthenticationRedirect = true;
response.End();// This line is causing the problems
return;
}
if (user.Identity.IsAuthenticated)
{
//Redirect to customerror page
}
}
Вопрос в том, когда я звоню метод с использованием AJAX поста, мой пользовательское исключением фильтр ловит ошибку говоря "Server cannot set status after HTTP headers have been sent "
Если удалить response.end(), я получаю 401 ответа в Аякса метод обработчика ошибок вместо 403. Я попытался
HttpContext.Current.ApplicationInstance.CompleteRequest()
вместо response.end, но тогда и я получаю 401 ошибку
Т здесь, во всяком случае, чтобы избежать этого исключения?
Update Я использую этот общий метод обработчика ошибок в JavaScript, чтобы поймать все ошибки Ajax запроса (нужно правильный код статуса для ответа):
function ajaxFailed(xhr, textstatus, errorthrown) {
debugger;
if (textstatus == "error") {
if (xhr.status == 401) {
window.location = "/Account/Login";
}
if (xhr.status == 403) {
$("#divoutput").html("you don't have permission.");
}
}
if (xhr.status == 500) {
$("#divoutput").append("<br/> internal servererror." + xhr.responseText);
}
}
Update 2: Мой текущий Решение: Проверьте свойство Exception.Message повышенного исключения в моем настраиваемом обработчике обработчика исключений и проигнорируйте его, если это сообщение: «Сервер не может установить статус после HTTP-заголовка s были отправлены ".
Я знаю, что это неэффективный метод, но у меня пока нет другого решения. Ожидание хорошее решение :)
if (filterContext.Result == null) всегда верно, если я это сделаю. – Sharun
Это потому, что проверки не проводились, но заголовки не были отправлены. – VMAtm
Я тебя не понимаю. Мне нужно сначала выполнить base.OnAuthorization (filterContext), чтобы свойство user.Identity.IsAuthenticated было правильно настроено. Затем в моем обычном методе я проверяю это значение, чтобы найти, является ли это проблемой аутентификации или проблемой авторизации. – Sharun