Почему SessionManagementFilter Spring Security работает, когда для моей политики создания сеанса установлено значение STATELESS?

У меня есть веб-приложение на основе 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 этого класса, и он будет запускаться при каждом запросе к серверу.

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

Спасибо.

Ваше понимание неверно. Он по-прежнему будет работать, но не будет создавать сеанс и не сохранять в нем данные. Будет SessionManagementFilter с NullSecurityContextRepository, который не будет хранить его. По сути, он всегда будет работать, но в зависимости от конфигурации он будет что-то делать или нет.

M. Deinum 12.06.2018 14:32

Хорошо, в этом есть смысл. Но когда он запускается, это вряд ли бесполезно. Метод doFilter вызывает метод onAuthentication, который зарегистрировал в качестве своей единственной стратегии делегирования ChangeSessionIdAuthenticationStrategy. Это может противоречить моей политике создания сеанса STATELESS. У меня нет явно заданной стратегии фиксации сеанса, которая, если я не ошибаюсь, по умолчанию будет migrateSession, но такое поведение подразумевает, что я каким-то образом использую changeSessionId. Я могу в конечном итоге опубликовать новый вопрос с этими выводами.

MegaMatt 12.06.2018 15:00

Что не должно быть проблемой, поскольку вы не создаете сеанс (по крайней мере, Spring Security не создает сеанс, что не означает, что что-то еще не создает сеанс!), Который в основном должен быть пустым. Поскольку стратегия сначала проверяет, существует ли уже сеанс, если нет, ничего не делайте. Тот факт, что Spring Security работает в режиме без сохранения состояния, не означает, что остальная часть вашего приложения автоматически становится без состояния!

M. Deinum 13.06.2018 07:59

Конечно, мое приложение является создает сеанс с использованием всегда работающего фильтра сервлетов (((HttpServletRequest) request).getSession()). И этот ChangeSessionIdAuthenticationStrategy, который работает, постоянно меняет мой JSESSIONID. Согласно документам Spring, значение NEVER для SessionCreationPolicy должно использовать HttpSession, если он существует, в то время как значение STATELESS «никогда не будет создавать HttpSession и никогда не будет использовать его для получения SecurityContext». Для меня это звучит так, как будто это не должно связываться с моим JSESSIONID. Я просто очень запутался, почему это мешает.

MegaMatt 13.06.2018 15:30

Это мешает, потому что работа в режиме без сохранения состояния и предотвращение атак фиксации сеанса - это две разные вещи. Здесь происходит то, что Spring Security обнаруживает сеанс, и по умолчанию безопасность, применяемая для предотвращения перехвата сеанса, заключается в изменении идентификатора сеанса. Если вы не хотите, указывайте, что это не должно быть ничего через sessionFixation().none(). Однако это сделает ваше приложение менее безопасным и уязвимым для атак фиксации сеанса. Я не понимаю, почему изменение идентификатора сеанса может привести к поломке, а то, что нарушается, должно быть исправлено вместо того, чтобы сделать ваше приложение менее безопасным.

M. Deinum 13.06.2018 15:45

Спасибо. Можете ли вы объединить свои комментарии в ответ, который я могу принять?

MegaMatt 13.06.2018 16:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
3 336
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При использовании Spring Security управление сеансом шире, чем сохранение аутентифицированного пользователя в сеансе (как описано в Секция управления сеансом Руководства по безопасности Spring).

HTTP session related functionality is handled by a combination of the SessionManagementFilter and the SessionAuthenticationStrategy interface, 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(); однако вы должны задаться вопросом, действительно ли это то, чего вы хотите, поскольку это потенциально делает ваше приложение менее безопасным.

В зависимости от того, что ломается / выходит из строя, вы можете исправить это вместо того, чтобы сделать ваше приложение менее безопасным.

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