У меня есть веб-приложение на основе J2EE REST, которое использует Spring Security 4.0.1.RELEASE. Я настраиваю Spring Security с конфигурацией на основе Java и установил для политики создания сеанса значение STATELESS, например:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(secureEnabled=true, prePostEnabled=true, jsr250Enabled=true, order=1)
public class DefaultSecurityBeansConfig extends WebSecurityConfigurerAdapter {
// ...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()...; // additional config omitted for brevity
// ...
}
// ...
}
Прочитав эта статья об управлении сеансами Spring Security, я считаю, что фильтр SessionManagementFilter должен работать в цепочке фильтров Spring Security. Но это определенно так. Я могу установить точку останова в методе doFilter этого класса, и он будет запускаться при каждом запросе к серверу.
Что здесь происходит? Тот факт, что этот фильтр работает, вызывает другое неожиданное поведение в моем приложении, которое, как я думал, было настроено отдельно.
Спасибо.
Хорошо, в этом есть смысл. Но когда он запускается, это вряд ли бесполезно. Метод doFilter вызывает метод onAuthentication, который зарегистрировал в качестве своей единственной стратегии делегирования ChangeSessionIdAuthenticationStrategy. Это может противоречить моей политике создания сеанса STATELESS. У меня нет явно заданной стратегии фиксации сеанса, которая, если я не ошибаюсь, по умолчанию будет migrateSession, но такое поведение подразумевает, что я каким-то образом использую changeSessionId. Я могу в конечном итоге опубликовать новый вопрос с этими выводами.
Что не должно быть проблемой, поскольку вы не создаете сеанс (по крайней мере, Spring Security не создает сеанс, что не означает, что что-то еще не создает сеанс!), Который в основном должен быть пустым. Поскольку стратегия сначала проверяет, существует ли уже сеанс, если нет, ничего не делайте. Тот факт, что Spring Security работает в режиме без сохранения состояния, не означает, что остальная часть вашего приложения автоматически становится без состояния!
Конечно, мое приложение является создает сеанс с использованием всегда работающего фильтра сервлетов (((HttpServletRequest) request).getSession()). И этот ChangeSessionIdAuthenticationStrategy, который работает, постоянно меняет мой JSESSIONID. Согласно документам Spring, значение NEVER для SessionCreationPolicy должно использовать HttpSession, если он существует, в то время как значение STATELESS «никогда не будет создавать HttpSession и никогда не будет использовать его для получения SecurityContext». Для меня это звучит так, как будто это не должно связываться с моим JSESSIONID. Я просто очень запутался, почему это мешает.
Это мешает, потому что работа в режиме без сохранения состояния и предотвращение атак фиксации сеанса - это две разные вещи. Здесь происходит то, что Spring Security обнаруживает сеанс, и по умолчанию безопасность, применяемая для предотвращения перехвата сеанса, заключается в изменении идентификатора сеанса. Если вы не хотите, указывайте, что это не должно быть ничего через sessionFixation().none(). Однако это сделает ваше приложение менее безопасным и уязвимым для атак фиксации сеанса. Я не понимаю, почему изменение идентификатора сеанса может привести к поломке, а то, что нарушается, должно быть исправлено вместо того, чтобы сделать ваше приложение менее безопасным.
Спасибо. Можете ли вы объединить свои комментарии в ответ, который я могу принять?




При использовании Spring Security управление сеансом шире, чем сохранение аутентифицированного пользователя в сеансе (как описано в Секция управления сеансом Руководства по безопасности Spring).
HTTP session related functionality is handled by a combination of the
SessionManagementFilterand theSessionAuthenticationStrategyinterface, which the filter delegates to. Typical usage includes session-fixation protection attack prevention, detection of session timeouts and restrictions on how many sessions an authenticated user may have open concurrently.
Сказать, что sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) не означает, что ваше приложение не имеет состояния, это означает, что Spring Security не будет создавать сеанс. Если в вашем приложении что-то еще создает сеанс, Spring Security попытается защитить его от атаки фиксации сеанса.
Как выполняется атака с фиксацией сеанса, зависит от настроенной стратегии; по умолчанию идентификатор сеанса изменяется при каждом запросе. В контейнерах Servlet 3.1 и новее ChangeSessionIdAuthenticationStrategy используется по умолчанию, если явная конфигурация не выполняется. В Servlet 3.0 и ниже по умолчанию используется migrateSession.
Вы можете отключить защиту от фиксации сеанса, выполнив sessionFixation().none(); однако вы должны задаться вопросом, действительно ли это то, чего вы хотите, поскольку это потенциально делает ваше приложение менее безопасным.
В зависимости от того, что ломается / выходит из строя, вы можете исправить это вместо того, чтобы сделать ваше приложение менее безопасным.
Ваше понимание неверно. Он по-прежнему будет работать, но не будет создавать сеанс и не сохранять в нем данные. Будет
SessionManagementFilterсNullSecurityContextRepository, который не будет хранить его. По сути, он всегда будет работать, но в зависимости от конфигурации он будет что-то делать или нет.