Запретить странице или обработчику обновлять билет FormsAuthentication

У меня есть несколько приложений в одном домене, которые совместно используют билет formauthentication для одиночной регистрации. У нас также есть javascript на каждой странице, который предупредит пользователя за 2 минуты до истечения срока его сеанса и позволит ему выйти из системы или продлить сеанс. Когда обратный отсчет достигает 0, они автоматически выходят из системы. Все это прекрасно работает. Однако это с треском проваливается, когда пользователь открывает несколько окон или вкладок браузера для работы с различными приложениями. Если время ожидания окна A истекло, пока пользователь работает в окне B, он выйдет из B при следующем запросе.

У меня есть решение, но я не могу его реализовать. В основном, когда страница отрисовывается, я выписываю галочками дату выдачи билета. Затем, при автоматическом выходе из системы, я хочу, чтобы ajax вызывал обработчик, чтобы увидеть, соответствуют ли эти тики текущим тикам билета формы. Если они не совпадают, то я знаю, что другое приложение обновляет тикет, и я не выйду из них. Проблема в том, что я не могу создать общий обработчик, который не обновляет тикет, потому что мы используем slideexpiration = true.

function CompareTicket(ticks) {
    $.getJSON('http://localhost/MyApp/CompareTicket.ashx?t=' + ticks, function (data) {
        if (data == 0)
            SessionEnd();
        else
            SessionExtend();
    });
}

В приведенном ниже коде обработчика данные возвращаются как 0, если значение, которое я отправляю в строке запроса, соответствует тикам текущего билета. К сожалению, простой запрос обработчика обновит билет и всегда отправит обратно новый счетчик тиков.

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "application/json";
        context.Response.ContentEncoding = Encoding.UTF8;

        long ticketTicks = ((FormsIdentity)context.User.Identity).Ticket.IssueDate.Ticks;
        if (ticketTicks == 0)
            context.Response.Write("0");
        else
        {
            long ticks = 0;
            if (long.TryParse(context.Request.QueryString["t"], out ticks))
            {
                if (ticketTicks == ticks)
                    context.Response.Write("0");
                else
                    context.Response.Write(ticketTicks.ToString());
            }
            else
                context.Response.Write("0");
        }
    }

Любые идеи о том, как получить запрос JSON с сервера без продления билета?


person Jason Butera    schedule 21.07.2011    source источник


Ответы (2)


В asp.net модули аутентификации жизненного цикла запроса выполняются перед httphandlers. Одним из обходных путей является удаление этих модулей аутентификации для определенного URL-адреса, чтобы при попадании httphandler он не продлевал ваш билет. что-то вроде этого

<location path="/MyApp/CompareTicket">
    <system.web>
        <httpModules>
            <remove name="FormsAuthenticationModule"/>
        </httpModules>
    </system.web>
</location>
person Sergey    schedule 13.07.2012

Чтобы понять это, у вас есть более одного приложения в домене, использующем один и тот же токен проверки подлинности с помощью форм для целей единого входа. Когда у одного приложения истекает срок действия токена, вы хотите, чтобы оно обнаруживало это во всех других «открытых» приложениях в то время.

Поскольку токен - это просто файл cookie, вы можете настроить непрерывно работающую функцию javascript (скажем, каждые 30 секунд), чтобы обнаруживать наличие файла cookie аутентификации форм. Если он исчезнет (так как это будет выход из системы / истечение срока действия), вы можете использовать скрипт, чтобы вызвать какое-то предупреждение и т. д.

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

person simbolo    schedule 08.10.2011