2010-10-22 3 views
2

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

Однако у меня также есть запросы 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 к Несанкционированное, запрос перенаправляется на мою страницу входа в систему, которая не подходит для Ajax запросов.

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

ответ

5

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

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

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

+0

хорошо звучит. Попробуем, спасибо. Является ли это изменено в любом случае в MVC 2 или 3? – Khash

+0

К сожалению, нет. Это похоже на MVC2 и 3. Я поднял его как проблему с командой MVC, но FormsAuthenticationis действительно не находится в пределах своей области ответственности. – Clicktricity

0

Один из способов решения этой проблемы - добавить текст, чтобы однозначно идентифицировать страницу входа в систему и использовать его в обратном вызове 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; 
    } 

}); 
+0

Это не очень хорошее решение, поскольку для этого требуется, чтобы все вызовы AJAX менялись и не были используя структуру страницы входа в ASP MVC. – Khash

+0

@Khash Вам не нужно менять все вызовы ajax. это глобальная привязка, которая может быть включена в одну общую страницу. –

1

Вы можете сделать свой собственный Авторизоваться фильтр, присущего от рамочной, и переопределить функцию, запись в ответ, когда пользователь не авторизован, не устанавливая код состояния, если запрос выполняется из 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

Возможно, я не смог правильно передать свой вопрос. Не имеет значения, выполняю ли я это в пользовательском атрибуте или коде, факт устанавливает, что StatusCode неавторизован перенаправляет клиент на страницу входа, которая не является AJAX. – Khash

Смежные вопросы