Различный ответ неаутентифицированным пользователям и вызовам AJAX - PullRequest
2 голосов
/ 22 октября 2010

Мой веб-сайт ASP MVC (1.0) имеет страницу входа по умолчанию (на основе OpenId - но это не должно измениться). Он работает нормально, когда AuthorizedAttribute находится на Action / Controller.

Тем не менее, у меня есть и AJAX-запросы. Вот что я с ними делаю:

if (Request.IsAjaxRequest())
{ 
  if (Request.IsAuthenticated)
  {
    // Authenticated Ajax request
  }
  else
  {
    // Non-authenticated Ajax request.
    Response.StatusCode = (int)HttpStatusCode.Unauthorized;
    return Json(new { response = "AUTHENTICATION_FAILED" });
   }
}

Проблема в том, что если я установил для Response.StatusCode значение Unauthorized, запрос перенаправляется на мою страницу входа, что не подходит для запросов Ajax.

Любые предложения по этому вопросу приветствуются.

Ответы [ 3 ]

5 голосов
/ 23 октября 2010

Это распространенная проблема.

Атрибут Authorize возвращает неавторизованный ответ по протоколу Http 401.К сожалению, однако, если вы включили FormsAuthentication, 401 перехватывается модулем FormsAuthenticationModule, который затем выполняет перенаправление на страницу входа в систему, которая затем возвращает Http 200 (и страницу входа в систему) обратно на ваш запрос ajax.

Лучшая альтернатива - изменить код авторизации так, чтобы он возвращал другой код состояния Http, скажем, 403, который не перехватывается модулем formsAuthenticationModule, и вы можете перехватить его в методе Ajax.

1 голос
/ 23 октября 2010

Вы можете создать свой собственный фильтр авторизации, свойственный фреймворку, и переопределить функцию записи в ответ, когда пользователь не авторизован, не устанавливая код состояния, если запрос поступил от ajax. Примерно так:

public class MyAutorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
            filterContext.Result = new JsonResult() { Data = new { response = "AUTHENTICATION_FAILED" } };
        else
            filterContext.Result = new HttpUnauthorizedResult();
    }
} 

А теперь в ваших действиях используйте новый атрибут

[MyAutorize]
public ActionResult myAction()  
{
  if (Request.IsAuthenticated) // You should not need to ask this here
  {
      // Authenticated Ajax request
  }
  else
  {
    // Non-authenticated Ajax request.
     Response.StatusCode = (int)HttpStatusCode.Unauthorized;
     return Json(new { response = "AUTHENTICATION_FAILED" });
  }
}
0 голосов
/ 23 октября 2010

Один из способов решения этой проблемы - добавить текст для уникальной идентификации страницы входа в систему и использовать его при обратном вызове AJAX, чтобы снова перенаправить на страницу входа. Вот пример кода с использованием глобальных обратных вызовов jQuery ....

$(document).bind("ajaxComplete", function(event, response, ajaxOptions) {
    if (response.status == 200 && response.responseText.match(/LOGIN_PAGE_UNIQUE_KEY/)) {
        self.location = "/web/login?timeout=1";
        return false;
    }

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...