ASP.NET истечение сессии MVC

У нас есть внутренний ASP.NET приложение MVC, которое требует входа в систему. Вход в систему работает отлично и делает то, что ожидается. У нас есть истечение сессии 15 минут. После нахождения на единственной странице в течение того промежутка времени пользователь проиграл сессию. Если они попытаются обновить текущую страницу или обзор другому, то они получат страницу входа в систему. Мы сохраняем их запрос сохраненным поэтому, после того как они вошли в систему, они могут продвинуться к странице, которую они запросили. Это работает отлично.

Однако моя проблема - то, что на некоторых страницах существуют вызовы Ajax. Например, они могут заполнить часть формы, блуждания прочь и позволить их сессии истечь. Когда они возвращаются, экран все еще отображен. Если они просто заполнят поле (который выполнит вызов Ajax), то вызов Ajax возвратит Страницу регистрации (в любом отделении, Ajax должен был просто возвратить фактические результаты). Это выглядит ужасным.

Я думаю, что решение состоит в том, чтобы заставить саму страницу истечь (так, чтобы, когда сессия завершается, они автоматически были возвращены к экрану входа в систему без любого действия ими). Однако я задаюсь вопросом, существуют ли мнения/идеи о том, как лучше всего реализовать это конкретно в отношении лучших практик в ASP.NET MVC.

Обновление:

Таким образом, я шел вперед и реализовал это в моем OnActionExecuting (на предложение Keltex)

  if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
  {
    if (filterContext.HttpContext.Request.IsAjaxRequest())
    {
      filterContext.HttpContext.Response.Write("Invalid session -- please login!");
      filterContext.HttpContext.Response.End();
    }
    else
    {
      ...
    }
  }

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

Я все еще думаю, что реализую обратный отсчет JavaScript также это предложенный womp.

14
задан Andrew Flanagan 7 April 2010 в 21:53
поделиться

4 ответа

В частности, я не знаю, есть ли какие-либо передовые методы в отношении этого, но я делаю это прямо сейчас для нашего приложения. Мы выбрали клиентское решение, в котором мы выводим значение тайм-аута сеанса в некоторый javascript на главной странице и вычисляем, когда истечет срок действия сеанса.

За 5 минут до этого мы открываем модальное диалоговое окно с вопросом: «Вы все еще там?» с таймером обратного отсчета. Как только таймер достигает 0:00, мы перенаправляем браузер на страницу входа.

Он реализован с минимальным количеством JavaScript для вычисления времени и таймера, а также с простым обработчиком .ashx, который обновит сеанс, если пользователь щелкнет «Я вернулся!» в диалоговом окне перед истечением сеанса. Таким образом, если они вернутся вовремя, они смогут обновить сеанс без какой-либо навигации.

16
ответ дан 1 December 2019 в 10:18
поделиться

Вчера я задавал аналогичный вопрос. Вот мое решение:

Измененный атрибут авторизации:

public class OptionalAuthorizeAttribute : AuthorizeAttribute
{
    private class Http403Result : ActionResult
    {
        public override void ExecuteResult(ControllerContext context)
        {
            // Set the response code to 403.
            context.HttpContext.Response.StatusCode = 403;
            context.HttpContext.Response.Write(CTRes.AuthorizationLostPleaseLogOutAndLogInAgainToContinue);
        }
    }

    private readonly bool _authorize;

    public OptionalAuthorizeAttribute()
    {
        _authorize = true;
    }

    //OptionalAuthorize is turned on on base controller class, so it has to be turned off on some controller. 
    //That is why parameter is introduced.
    public OptionalAuthorizeAttribute(bool authorize)
    {
        _authorize = authorize;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //When authorize parameter is set to false, not authorization should be performed.
        if (!_authorize)
            return true;

        var result = base.AuthorizeCore(httpContext);

        return result;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            //Ajax request doesn't return to login page, it just returns 403 error.
            filterContext.Result = new Http403Result();
        }
        else
            base.HandleUnauthorizedRequest(filterContext);
    }
}

HandleUnauthorizedRequest переопределен, поэтому он возвращает Http403Result при использовании Ajax. Http403Result изменяет StatusCode на 403 и в ответ возвращает сообщение пользователю. В атрибуте есть дополнительная логика (параметр authorize ), потому что я включаю [Authorize] в базовом контроллере и отключаю его на некоторых страницах.

Другой важной частью является глобальная обработка этого ответа на стороне клиента. Это то, что я поместил в Site.Master:

<script type="text/javascript">
    $(document).ready(
        function() {
            $("body").ajaxError(
                function(e,request) {
                    if (request.status == 403) {
                        alert(request.responseText);
                        window.location = '/Logout';
                    }
                }
            );
        }
    );
</script>

Я размещаю ГЛОБАЛЬНЫЙ обработчик ошибок ajax, и когда evert $. Post завершается с ошибкой 403, появляется ответное сообщение и пользователь перенаправляется на страницу выхода. Теперь мне не нужно обрабатывать ошибки в каждом запросе $. Post , потому что он обрабатывается глобально.

Почему 403, а не 401? 401 обрабатывается внутри MVC framework (поэтому перенаправление на страницу входа выполняется после неудачной авторизации).

Что вы думаете об этом?

РЕДАКТИРОВАТЬ:

Об отказе от атрибута [Authorize]: [Authorize] - это не только проверка Identity.IsAuthenticated.Он также обрабатывает кеширование страниц (поэтому вы не кешируете материал, требующий аутентификации) и перенаправление. Копировать этот код не нужно.

7
ответ дан 1 December 2019 в 10:18
поделиться

Вы можете изучить AjaxOptions, которые можно установить в Ajax.BeginForm (). Существует параметр OnBegin, который можно связать с функцией javascript, которая может вызывать метод контроллера, чтобы подтвердить, что сеанс все еще действителен, а если нет, перенаправить на страницу входа в систему, используя window.location .

2
ответ дан 1 December 2019 в 10:18
поделиться

Отчасти проблема, похоже, в том, что вы позволяете фреймворку делать все. Я бы не стал украшать ваш метод AJAX атрибутом [Authorize] . Вместо этого проверьте User.Identity.IsAuthenticated и, если он вернет false, создайте разумное сообщение об ошибке.

1
ответ дан 1 December 2019 в 10:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: