Я использую безопасность Spring RememberMe Services для хранения пользователя аутентифицируемым.
Я хотел бы найти простой способ установить RememberMe cookie как сеансовые куки, а не с фиксированным временем истечения срока. Для моего приложения должен сохраниться cookie, пока пользователь не закрывает браузер.
Какие-либо предложения о том, как лучше всего реализовать это? Какие-либо проблемы на этом являющемся возможной проблемой защиты?
Основная причина того, чтобы сделать так - то, что с основанным на cookie маркером, любой из серверов позади нашей подсистемы балансировки нагрузки может обслужить защищенный запрос, не полагаясь на Аутентификацию пользователя, которая будет сохранена в HttpSession. На самом деле я явно сказал Spring Security никогда не создавать сессии с помощью пространства имен. Далее, мы используем Эластичное Выравнивание нагрузки Amazon, и таким образом, липкие сессии не поддерживаются.
NB: Хотя я знаю, что с 08 апреля, Amazon теперь поддерживает липкие сессии, я все еще, не хочет использовать их по горстке других причин. А именно, то, что несвоевременный упадок одного сервера все еще вызвал бы потерю сессий для всех пользователей, связанных с ним. http://aws.amazon.com/about-aws/whats-new/2010/04/08/support-for-session-stickiness-in-elastic-load-balancing/
Чтобы сеанс работал правильно с балансировкой нагрузки, я бы данные вашей сессии хранятся в базе данных sql.
Файл cookie всегда должен быть случайным значением, срок действия которого истекает. Бывают случаи, когда вы можете сохранить состояние как значение cookie, и это не будет опасной угрозой, например, предпочтительный язык пользователя, но этого следует по возможности избегать. Включение HttpOnlyCookies - отличная идея.
Прочтите A3: «Сломанная аутентификация и управление сеансом» в топ-10 OWASP за 2010 год. Важным моментом в этом разделе является то, что https должен использоваться для всего сеанса. Если сеанс длится очень долго, то это тем более важно.
Также имейте в виду, что «Запомнить меня» создает большое окно, в котором злоумышленник может «оседлать» сеанс. Это дает злоумышленнику очень долгое время (месяцы?), В течение которого он может выполнить CSRF-атаку. Даже если у вас есть защита CSRF, злоумышленник все равно может использовать сеанс с XSS и XmlHttpRequest (HttpOnlyCookies предотвратит полный захват). «Помни меня» делает другие угрозы, такие как xss, csrf, более серьезными. Пока эти уязвимости устранены, у вас не должно возникнуть проблем с хакерами из реального мира.
Самый простой (и безопасный) подход к реализации функции «запомнить меня» - это изменить тайм-аут сеанса, чтобы сделать его очень большим (несколько месяцев).Если флажок «запомнить меня» снят, сохраните переменную сеанса с новым тайм-аутом (1 день с момента входа в систему). Имейте в виду, что даже если файл cookie удаляется браузером при закрытии, сеанс все еще активен на стороне сервера. Если идентификатор сеанса украден, его все еще можно использовать.
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"/>