Проверка на http авторизацию в mvc перед публикацией формы ajax - PullRequest
5 голосов
/ 15 мая 2009

При создании системы управления контентом, которая включает jquery ajax в свой графический интерфейс, я столкнулся с препятствием. Кажется, что некоторые клиенты тратят слишком много времени на размышления о том, что они собираются написать, и, следовательно, серверная сессия выводит их из системы, естественно, будучи в сети, они понятия не имеют об этом. Когда они пытаются отправить изменения, я использую ajax-вызов на сервер для сохранения данных.

То, что я ожидаю, произойдет дальше, так это то, что приложение сервера MVC вернет статус «401 Unauthorized». Затем я мог бы получить свой jjery ajax-объект, чтобы попросить пользователя войти в систему, а затем повторно отправить изменения после авторизации пользователя.

Однако на самом деле из приложения MVC возвращается статус «302 найдено» и URL-адрес перенаправления на мою страницу формы входа. Страница формы входа возвращает код состояния «200 OK», а объект jquery ajax вызывает событие успеха, которое сообщает пользователю, что все прошло успешно, потому что это то, что говорит приложение MVC.

Есть ли способ заставить приложение MVC играть так, как я думаю, или мне нужно изменить события jjery ajax для обнаружения страницы входа?

Обновление:

Я использовал рефлектор, чтобы взглянуть на код MVC и атрибут авторизации, вернуть NotAuthorizedResult, код которого приведен ниже (0x191 = 401)

public override void ExecuteResult(ControllerContext context)  
{  
    if (context == null)  
    {  
        throw new ArgumentNullException("context");  
    }  
    context.HttpContext.Response.StatusCode = 0x191;  
}

Я думаю, что, возможно, HttpModule для авторизации форм просматривает 401 и форсирует перенаправление.

Ответы [ 3 ]

6 голосов
/ 15 мая 2009

вы можете попробовать что-то вроде этого:

    void context_EndRequest(object sender, EventArgs e)
    {
        var app = sender as HttpApplication;
        var response = app.Response;
        var request = app.Request;

        if ((response.StatusCode == 302) && IsAjaxRequest(request))
            response.StatusCode = 401;
    }

в модуле HttpModule, он будет после модуля FormsAuth последовательно, поэтому исправит код состояния. Не красиво, но эффективно.

5 голосов
/ 15 июля 2011

Мне очень нравится это решение. Изменяя ответ 302 на запросы AJAX на 401, он позволяет вам настроить ваш AJAX на стороне клиента для отслеживания любого запроса AJAX, ищущего 401, и если он находит его для перенаправления на страницу входа. Очень просто и эффективно.

Global.asax:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302 &&
        Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

Код на стороне клиента:

 $(function () {
      $.ajaxSetup({
        statusCode: {
          401: function () {
            location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
          }
        }
      });
    });
1 голос
/ 17 января 2012

Я обнаружил, что более легкий подход состоит в том, чтобы просто добавить пользовательский заголовок HTTP на страницу входа и затем проверить его наличие в обратном вызове успеха AJAX.

Т.е.. в LoginController (это проект MVC, но тот же принцип должен применяться к другим решениям ASP.NET):

public ActionResult Login(string returnUrl = "")
{
    Response.AddHeader("X-Unauthorized", "true");
    ...

А затем в клиентском обработчике AJAX:

success: function(data, textStatus, jqXhr)
{
    if (jqXhr.getResponseHeader("X-Unauthorized"))
    {
        ...

Это работает для меня, по крайней мере.

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