Ответ 1
-
Это кажется невозможным. После того, как разрешение на выключение включено, оно всегда срабатывает. Если есть доступ к сеансу без его расширения, мы не смогли его найти.
-
Итак, как решить этот сценарий? Мы пришли к следующему альтернативному решению, которое первоначально было предложено в вопросе. Это действительно более эффективно, потому что он не использует веб-службу для дома домой каждые х секунд.
Таким образом, мы хотим узнать, когда устарела или прошла аутентификация или сеанс ASP.NET, поэтому мы можем активно выходить из системы пользователем. Простой javascript-таймер на каждой странице (как предлагалось Халидом Абухакмехом) не будет достаточным, потому что пользователь может одновременно работать с приложением в нескольких окнах/вкладках браузера.
Первое решение, которое мы сделали для упрощения этой проблемы, - сделать время истечения срока действия сеанса на несколько минут дольше, чем время истечения срока действия проверки подлинности форм. Таким образом, сеанс никогда не истечет до проверки подлинности форм. Если в предыдущем сеансе есть затяжная старая сессия, пользователь в следующий раз попытается войти в систему, мы оставим ее, чтобы создать новую новую.
Хорошо, так что теперь нам нужно только учитывать срок действия проверки подлинности форм.
Затем мы решили отключить автоматическое скользящее окончание аутентификации форм (как установлено в web.config) и создать нашу собственную версию.
public static void RenewAuthenticationTicket(HttpContext currentContext)
{
var authenticationTicketCookie = currentContext.Request.Cookies["AuthTicketNameHere"];
var oldAuthTicket = FormsAuthentication.Decrypt(authenticationTicketCookie.Value);
var newAuthTicket = oldAuthTicket;
newAuthTicket = FormsAuthentication.RenewTicketIfOld(oldAuthTicket); //This triggers the regular sliding expiration functionality.
if (newAuthTicket != oldAuthTicket)
{
//Add the renewed authentication ticket cookie to the response.
authenticationTicketCookie.Value = FormsAuthentication.Encrypt(newAuthTicket);
authenticationTicketCookie.Domain = FormsAuthentication.CookieDomain;
authenticationTicketCookie.Path = FormsAuthentication.FormsCookiePath;
authenticationTicketCookie.HttpOnly = true;
authenticationTicketCookie.Secure = FormsAuthentication.RequireSSL;
currentContext.Response.Cookies.Add(authenticationTicketCookie);
//Here we have the opportunity to do some extra stuff.
SetAuthenticationExpirationTicket(currentContext);
}
}
Мы вызываем этот метод из события OnPreRenderComplete
в нашем классе BasePage приложения, из которого наследуется каждая другая страница. Он делает то же самое, что и функциональность обычного сползания, но мы получаем возможность делать некоторые дополнительные вещи; как вызов нашего метода SetAuthenticationExpirationTicket
.
public static void SetAuthenticationExpirationTicket(HttpContext currentContext)
{
//Take the current time, in UTC, and add the forms authentication timeout (plus one second for some elbow room ;-)
var expirationDateTimeInUtc = DateTime.UtcNow.AddMinutes(FormsAuthentication.Timeout.TotalMinutes).AddSeconds(1);
var authenticationExpirationTicketCookie = new HttpCookie("AuthenticationExpirationTicket");
//The value of the cookie will be the expiration date formatted as milliseconds since 01.01.1970.
authenticationExpirationTicketCookie.Value = expirationDateTimeInUtc.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds.ToString("F0");
authenticationExpirationTicketCookie.HttpOnly = false; //This is important, otherwise we cannot retrieve this cookie in javascript.
authenticationExpirationTicketCookie.Secure = FormsAuthentication.RequireSSL;
currentContext.Response.Cookies.Add(authenticationExpirationTicketCookie);
}
Теперь у нас есть дополнительный файл cookie, который всегда представляет собой правильное время истечения срока аутентификации, даже если пользователь работает в разных окнах/вкладках браузера. В конце концов, файлы cookie имеют широкий охват браузера. Теперь остается только функция javascript для проверки значения cookie.
function CheckAuthenticationExpiration() {
var c = $.cookie("AuthenticationExpirationTicket");
if (c != null && c != "" && !isNaN(c)) {
var now = new Date();
var ms = parseInt(c, 10);
var expiration = new Date().setTime(ms);
if (now > expiration) location.reload(true);
}
}
(Обратите внимание, что мы используем jQuery Cookie Plugin для извлечения файла cookie.)
Поместите эту функцию в интервал, и пользователи будут выходить из системы в тот момент, когда истек срок его аутентификации. Voilà:-) Дополнительным преимуществом этой реализации является то, что теперь у вас есть контроль над тем, когда срок действия проверки подлинности форм расширяется. Если вам нужна куча веб-сервисов, которые не продлевают срок действия, просто не вызывайте для них метод RenewAuthenticationTicket
.
Пожалуйста, оставьте комментарий, если вам есть что добавить!