Куки-файлы asp.net, аутентификация и время ожидания сеанса

У меня есть сайт asp.net, который использует аутентификацию форм. Есть несколько вещей, которые я держу в сессиях, таких как имя пользователя, идентификатор пользователя, электронная почта и т. Д.

Я разрешаю пользователю оставаться на веб-сайте, установив длинный срок действия файла cookie для аутентификации. Таким образом, для сессии очень часто истекает время, пока пользователь все еще аутентифицирован.

Проблема, с которой я сталкиваюсь, заключается в том, что иногда время сеанса пользователя истекает, но он все еще аутентифицируется. Так, например, одна из моих пользовательских страниц (которая требует аутентификации) будет говорить "Добро пожаловать, Майк", когда их сеанс активен, но когда он закончится, он будет говорить "Добро пожаловать [пусто]", потому что информация больше не находится в сеансе, но они все еще аутентифицированы.

Какой лучший способ справиться с этим? Должен ли я повторно синхронизировать информацию о сеансе, когда информации больше нет? Или мне следует переместить информацию о пользователе (имя пользователя, идентификатор пользователя, адрес электронной почты) в файлы cookie и не беспокоиться о тайм-ауте сеанса?

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

5 ответов

Решение

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

Файлы cookie для проверки подлинности форм зашифрованы, и вы можете добавить дополнительные данные в эти файлы cookie (подробности см. Ниже). Это возможно взломать, но не так просто, как простое печенье.

Вот код, который я использовал в прошлом, слегка модифицированный, чтобы удалить некоторые детали проекта. Вызовите это в событии LoggedIn элемента управления входом.

void AddUserIDToAuthCookie(string userID)  
{  
  //There is no way to directly set the userdata portion of a FormAuthenticationTicket  
  //without re-writing the login portion of the Login control  
  //  
  //I find it easier to pull the cookie that the Login control inserted out  
  //and create a new cookie with the userdata set  

  HttpCookie authCookie = Response.Cookies[AUTH_COOKIE];
  if(authCookie == null)
  {
    return;
  }

  Response.Cookies.Remove(AUTH_COOKIE);

  FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(authCookie.Value);
  var newTicket =
    new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, oldTicket.IssueDate, oldTicket.Expiration,
                                  oldTicket.IsPersistent, userID, oldTicket.CookiePath);

  authCookie.Value = FormsAuthentication.Encrypt(newTicket);

  Response.Cookies.Add(authCookie);
}

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

Чтобы получить идентификатор на своей веб-странице...

FormsAuthenticationTicket ticket = ((FormsIdentity) Page.User.Identity).Ticket;
string id = ticket.UserData;

Я использовал этот механизм для хранения идентификатора, который не был частью пользовательских данных aspnetdb. Если все ваши идентификационные данные обрабатываются aspnetdb, вам может потребоваться только доступ к объекту Page.User.Identity.

Лично я бы оставил 20-минутное значение по умолчанию и добавил бы функциональность "поддерживать активность" на ваш сайт. Создайте простой javascript, который опрашивает, скажем, heartbeat.aspx, каждые 5 минут, чтобы поддерживать сессию. Это продлит сеанс и аутентификацию, не сохраняя сумасшедших токенов аутентификации.

Есть несколько примеров (на мой взгляд, плохих) того, как это сделать. Я закончил тем, что использовал что-то, основанное на предотвращении тайм-аута сеанса AjaxLines. Вместо того, чтобы использовать библиотеку ajax, я просто использовал запрос xhtml напрямую. Ничего действительно не нужно больше, чем синхронизированный вызов javascript к GET на странице сердцебиения.

Технически из-за тайм-аута сессии asp.net ваш пользователь не должен выходить из системы. Это должно / контролируется куки-файлами аутентификации форм.

Вся необходимая информация, связанная с аутентификацией пользователя, должна храниться в свойстве USERDATA билета аутентификации форм. Это значение не должно храниться в сеансе как сеанс.

Сохраняйте только те значения, которые можно восстановить.

Таким образом, когда вы создаете cookie для аутентификации форм, вы можете передавать всю необходимую информацию как часть заявки.

-

Самое быстрое, что вы можете сделать, это сохранить время ожидания сеанса и проверки подлинности форм одинаковыми. Это будет хорошей практикой.

Время ожидания сеанса автоматически увеличивается с каждым запросом к сайту.

В то время как проверка подлинности с помощью форм продлевает свое время только по истечении 50% времени.

Вот подробная информация об этом: FAQ по проверке подлинности с помощью форм

Самое простое, что можно сделать, это продлить время проверки подлинности с помощью форм в пользовательском HttpModule или базовой странице, какой бы ни был ваш дизайн.

Таким образом, ваш тайм-аут всегда будет синхронизирован, хотя может быть небольшой разрыв.

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

Чтобы упростить это, создайте класс, добавьте свойство для каждой переменной в сеансе и сохраните экземпляр класса в сеансе. Затем создайте статический метод, чтобы получить экземпляр класса. Я добавлю пример позже, если бы мог.

Сам ничего не пробуя, есть несколько вещей, которые я бы проверил.

  • Используйте метод / перегрузку класса FormsAuthentication, который позволяет вам установить постоянный файл cookie. Хотя, IMHO, это обычная вежливость, когда ваши пользователи предпочитают устанавливать флажок "запомнить меня", а не заставлять их постоянно входить в систему. Существует ряд методов, которые позволяют вам делать это в зависимости от того, какое поведение вы хотите - SetAuthenticationCookie() и RedirectFromLoginPage() - первые, которые приходят на ум.

  • Проверьте FormsAuthentication.GetAuthenticationCookie(). Это создаст файл cookie HTTP с токеном аутентификации, но на самом деле не установит его, что должно позволить вам изменить то, что вы хотите - хотя, если модуль FormsAuthentication ищет определенное значение, связывание с ним может нарушить аутентификацию. Затем вам нужно будет добавить куки в коллекцию куки в ответе вручную.

Другие вопросы по тегам