Как аннулировать сессии пользователей, когда делает выход? - PullRequest
2 голосов
/ 20 декабря 2011

Я потратил много времени на решение этой проблемы, но все еще не мог заставить ее работать.

Я использую Spring Security. Приложение будет работать на нескольких серверах. Я использую опцию «запомнить меня» при входе в систему, чтобы сохранить постоянные входы в мою базу данных.

Если пользователь подключен к серверу 1, у него есть идентификатор сеанса в браузере файлов cookie. Я включаю другой сервер, и этот пользователь выполняет аутентификацию, а браузер cookie имеет этот идентификатор сеанса и идентификатор сеанса соединения с сервером 1.

Когда этот пользователь выходит из системы на том или ином сервере, он должен быть перенаправлен на страницу входа на всех серверах.

Я безуспешно пытался удалить куки из браузера. Как я могу сделать эту работу? Любая помощь?

Пример сценария: В gmail, если в вашей учетной записи открыто 2 вкладки, и если вы выходите из одной из них, другая вкладка также автоматически выходит из системы. Сервер 1 не знает информацию о сервере 2. Я думаю, что моя проблема здесь, но я не знаю, как я могу решить эту проблему.

Это моя конфигурация безопасности:

<http auto-config="false" use-expressions="true" disable-url-rewriting="true">
   <intercept-url pattern="/login.do" access="permitAll" />
   <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
   <remember-me data-source-ref="dataSource" />
   <form-login login-page="/login.do" />
   <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
   <custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
   <session-management session-authentication-strategy-ref="sas" />
</http>

<!-- <logout logout-url="/j_spring_security_logout" logout-success-url="/" invalidate-session="true" /> -->

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
   <beans:constructor-arg value="/login.do" />
   <beans:constructor-arg>
      <beans:list>
         <beans:ref bean="rememberMeServices"/>
         <beans:ref bean="logoutHandler"/>
      </beans:list>
   </beans:constructor-arg>
   <!-- <beans:property name="filterProcessesUrl" value="/login.do" /> -->
</beans:bean>

<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
   <beans:property name="sessionRegistry" ref="sessionRegistry" />
   <beans:property name="expiredUrl" value="/login.do" />
</beans:bean>

<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
   <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
   <beans:property name="maximumSessions" value="1" />
</beans:bean>

<authentication-manager alias="authenticationManager">
   <authentication-provider user-service-ref="jdbcUserService" />
</authentication-manager>

Ответы [ 2 ]

5 голосов
/ 21 декабря 2011

Вот 3 решения для вашего сценария с несколькими серверами:

  1. Используйте липкие сессии на вашем балансировщике нагрузки, чтобы пользователь продолжал возвращаться к тому же серверу. Тогда вы просто лишаете законной силы сеанс, когда они выходят из системы. Обычно это связано с решением восстановления после отказа сеанса ( пример Tomcat ), поэтому, если сервер выходит из строя, пользователь может быть перенаправлен на новый сервер, который забирает свой старый сеанс.

  2. Использовать распределенный кеш для сеансов (например, Терракотовые веб-сеансы) . Затем, когда они выйдут из системы, сделайте недействительным сеанс, и он будет недействительным везде.

  3. Другое решение заключается в использовании настроенного Spring Security TokenBasedRememberMeServices в качестве файла cookie для входа в систему. Если пользователь не выбирает запомнить меня, продолжайте и установите cookie, но сделайте его cookie сеанса браузера вместо постоянного cookie. Все серверы распознают пользователя и создадут для него сеанс. Когда пользователь выходит из системы, удалите cookie. Вам также понадобится пользовательский RememberMeAuthenticationFilter, который ищет токен аутентификации в сеансе и отсутствующий cookie RememberMe, делает недействительным сеанс и очищает контекст безопасности, если это так.

1 голос
/ 20 декабря 2011

Я бы порекомендовал вам взглянуть на SessionRegistry. Вы можете проверить это здесь . Об этом шла дискуссия на Возможно ли сделать недействительным весенний сеанс безопасности? . Проверьте это тоже

Весенние сессии хранятся в виде файлов cookie JsessionID. Проверьте здесь для обсуждения удаления куки.

Тот же запрос обсуждался на Недопустимый сеанс, когда пользователь выходит из системы (Spring) .

...