Сервисы RememberMe Spring Security с сессионным cookie-файлом

Я использую Spring Security RememberMe Services для аутентификации пользователя.

Я хотел бы найти простой способ установить файл cookie RememberMe как файл cookie сеанса, а не с фиксированным сроком действия. В моем приложении файл cookie должен сохраняться до тех пор, пока пользователь не закроет браузер.

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

Основная причина этого заключается в том, что с помощью токена на основе файлов cookie любой из серверов, стоящих за нашим балансировщиком нагрузки, может обслуживать защищенный запрос, не полагаясь на аутентификацию пользователя, которая будет храниться в HttpSession. Фактически, я прямо сказал Spring Security никогда не создавать сеансы с использованием пространства имен. Кроме того, мы используем эластичную балансировку нагрузки Amazon, поэтому липкие сеансы не поддерживаются.

NB: Хотя мне известно, что с 8 апреля Amazon теперь поддерживает липкие сеансы, я по-прежнему не хочу использовать их по ряду других причин. А именно, что безвременная остановка одного сервера все равно приведет к потере сеансов для всех пользователей, связанных с ним. http://aws.amazon.com/about-aws/whats-new/2010/04/08/support-for-session-stickiness-in-elastic-load-balancing/


person Jarrod Carlson    schedule 09.04.2010    source источник
comment
Почему бы вам просто не реализовать свою собственную реализацию RememberMe? Это довольно просто.   -  person lexicore    schedule 09.04.2010
comment
Дубликат? stackoverflow.com/questions/2594960 /   -  person rook    schedule 09.04.2010
comment
Люди @lexicore, реализующие свои собственные сеансы, могут нанести серьезный ущерб вашему веб-приложению. Не изобретайте заново волдырь. Читали мой пост по дубликату? вопрос выше.   -  person rook    schedule 09.04.2010
comment
@The Rook: Не думаю, что это дубликат. Джарроду просто нужно другое время истечения срока действия куки, вот и все.   -  person lexicore    schedule 09.04.2010
comment
@lexicore Это было в основном мое предложение для другого поста.   -  person rook    schedule 09.04.2010
comment
@The Rook: Ваше предложение не отвечает на вопрос - как это сделать с помощью Spring Security. Или я что-то упускаю?   -  person lexicore    schedule 09.04.2010
comment
@lexicore процесс такой же. Увеличьте срок службы сеанса с помощью диспетчера сеансов, а затем сохраните переменную сеанса, если вы хотите, чтобы срок ее действия истек раньше, в зависимости от выбора пользователя.   -  person rook    schedule 09.04.2010


Ответы (2)


Spring Security 3 не предлагает настройки того, как создается файл cookie. Вы должны изменить поведение по умолчанию:

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

/** Cookie expires on session. */
 public class PersistentTokenBasedRememberMeServicesCustom extends
   PersistentTokenBasedRememberMeServices {

  /** only needed because super throws exception. */
  public PersistentTokenBasedRememberMeServicesCustom() throws Exception {
    super();
  }

  /** Copy of code of inherited class + setting cookieExpiration, */
  @Override
  protected void setCookie(String[] tokens, int maxAge,
      HttpServletRequest request, HttpServletResponse response) {
    String cookieValue = encodeCookie(tokens);
    Cookie cookie = new Cookie(getCookieName(), cookieValue);
    //cookie.setMaxAge(maxAge); 
    cookie.setPath("/");
    cookie.setSecure(false); // no getter available in super, so always false

    response.addCookie(cookie);
  }
}

Убедитесь, что вы используете этот настроенный PersistentTokenBasedRememberMeServices для себя RememberMeService, добавив имя класса в его конфигурацию bean-компонента:

<beans:bean id="rememberMeServices"
 class="my.custom.spring.PersistentTokenBasedRememberMeServicesCustom"/>
person Kdeveloper    schedule 23.04.2010

Чтобы сеанс работал правильно с балансировкой нагрузки, я бы сохранил данные вашего сеанса в базе данных sql.

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

Прочтите A3: «Сломанная аутентификация и управление сеансом» в топ-10 OWASP за 2010 год. Важным моментом в этом разделе является то, что https должен использоваться для всего сеанса. Если сеанс длится очень долго, то это тем более важно.

Также имейте в виду, что «Запомнить меня» создает большое окно, в котором злоумышленник может «оседлать» сеанс. Это дает злоумышленнику очень долгое время (месяцы?), В течение которого он может выполнить CSRF-атаку. Даже если у вас есть защита CSRF, злоумышленник все равно может использовать сеанс с XSS и XmlHttpRequest (HttpOnlyCookies предотвратит полный захват). «Помни меня» делает другие угрозы, такие как xss, csrf, сниффинг, более серьезными. Пока эти уязвимости устранены, у вас не должно возникнуть проблем с хакерами из реального мира.

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

person rook    schedule 09.04.2010
comment
А как насчет настраиваемого фильтра RememberMe, который создает новый токен при каждом запросе. Новый токен может иметь короткий срок службы, например 20 минут. Если пользователь ничего не делает, срок действия токена истекает. Если пользователь делает другой запрос в 20-минутном окне, создается новое 20-минутное окно. Если сеанс пользователя каким-то образом украден, изменение пароля пользователя все равно приведет к аннулированию любых действительных токенов в дикой природе ... мысли? - person Jarrod Carlson; 14.04.2010
comment
Я помню, где я слышал об этой идее раньше ... она требует сохранения токена в базе данных, но не HttpSession: jaspan. com / Superior_persistent_login_cookie_best_practice Возможно, я изучу создание подкласса PersistentTokenBasedRememberMeService в Spring Security. - person Jarrod Carlson; 14.04.2010