куки-файлы asp.net, аутентификация и время ожидания сеанса - PullRequest
33 голосов
/ 18 января 2009

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

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

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

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

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

Ответы [ 5 ]

18 голосов
/ 18 января 2009

Старайтесь не использовать сессию как можно дольше, если вы можете уйти без всяких забот, это значительно облегчает развертывание на нескольких серверах. Вероятно, имя и адрес электронной почты являются легкими кандидатами на использование файлов 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.

4 голосов
/ 18 января 2009

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

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

2 голосов
/ 18 января 2009

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

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

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

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

-

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

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

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

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

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

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

0 голосов
/ 10 октября 2014

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

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

0 голосов
/ 18 января 2009

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

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

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

...