У меня есть слушатель, который динамически устанавливает время ожидания сеанса
public class DynamicSessionTimeoutHttpSessionListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent event) {
long sessionTimeoutInMinute = ConfigEntryMgr.getInstance().getByKeyAsLong(ConfigEntryKeys.SESSION_TIMEOUT_IN_MINUTE);
event.getSession().setMaxInactiveInterval((int) sessionTimeoutInMinute * 60);
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
}
}
В весенней безопасности я не разрешаю одновременную сессию:
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
<beans:property name="exceptionIfMaximumExceeded" value="true" />
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
В результате никто не может войти в систему с именем пользователя, который уже вошел в систему.
Проблема в том, что setMaxInactiveInterval не уничтожает весеннюю сессию.
Если только первый пользователь снова не откроет браузер и не выполнит действие, сервлет не обнаружит, что у сеанса истек срок действия для запуска SessionDestroyedEvent.
Теперь, если первый пользователь просто закроет свой браузер, никто не сможет войти в систему с этим пользователем навсегда, потому что Spring Security считает, что кто-то еще вошел в систему с этим именем пользователя