title: Spring-security : Maintaing active sessions even after JVM restart
body: <p>I am working on a Spring-MVC project running on Tomcat in which I have Spring-security for authentication and authorization. As our project is currently in development, we have more deployments than usual. Generally what happens after a deployment is that all the clients are logged out as the server is restarted.</p>
  
  <p>Is there any way where I can put the session-data in database or somewhere, so even after Tomcat/JVM crashes/restarts, already logged-in users wont have a problem. </p>
  
  <p>Is there any strategy to solving this problem? Any idea how? </p>
  
  <p>security-applicationContext.xml :</p>
  
  <pre><code> &lt;!-- Global Security settings --&gt;
      &lt;security:http pattern="/resources/template/demo/clients" security="none"/&gt;
  
      &lt;security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true"&gt;
          &lt;security:form-login login-page="/login" username-parameter="j_username" password-parameter="j_password"
                               login-processing-url="/j_spring_security_check" default-target-url="/dashboard"
                               always-use-default-target="true" authentication-failure-url="/denied"/&gt;
          &lt;security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService"
                                token-validity-seconds="1209600" data-source-ref="dataSource"/&gt;
          &lt;security:logout delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout"/&gt;
       &lt;!--&lt;security:intercept-url pattern="/**" requires-channel="https"/&gt;--&gt;
          &lt;security:port-mappings&gt;
              &lt;security:port-mapping http="80" https="443"/&gt;
          &lt;/security:port-mappings&gt;
          &lt;security:logout logout-url="/logout" logout-success-url="/" success-handler-ref="myLogoutHandler"/&gt;
  
          &lt;security:session-management session-fixation-protection="migrateSession"&gt;
              &lt;security:concurrency-control session-registry-ref="sessionReg" max-sessions="5" expired-url="/login"/&gt;
          &lt;/security:session-management&gt;
      &lt;/security:http&gt;
  
      &lt;beans:bean id="sessionReg" class="org.springframework.security.core.session.SessionRegistryImpl"/&gt;
  
      &lt;beans:bean id="rememberMeAuthenticationProvider"
                  class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices"&gt;
          &lt;beans:constructor-arg index="0" value="_spring_security_remember_me"/&gt;
          &lt;beans:constructor-arg index="1" ref="userDetailsService"/&gt;
          &lt;beans:constructor-arg index="2" ref="jdbcTokenRepository"/&gt;
          &lt;property name="alwaysRemember" value="true"/&gt;
      &lt;/beans:bean&gt;
  
      &lt;beans:bean id="jdbcTokenRepository"
                  class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"&gt;
          &lt;beans:property name="createTableOnStartup" value="false"/&gt;
          &lt;beans:property name="dataSource" ref="dataSource"/&gt;
      &lt;/beans:bean&gt;
  
      &lt;!-- Remember me ends here --&gt;
      &lt;security:authentication-manager alias="authenticationManager"&gt;
          &lt;security:authentication-provider user-service-ref="LoginServiceImpl"&gt;
              &lt;security:password-encoder ref="encoder"/&gt;
          &lt;/security:authentication-provider&gt;
      &lt;/security:authentication-manager&gt;
  
      &lt;beans:bean id="encoder"
                  class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"&gt;
          &lt;beans:constructor-arg name="strength" value="11"/&gt;
      &lt;/beans:bean&gt;
  
      &lt;beans:bean id="daoAuthenticationProvider"
                  class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"&gt;
          &lt;beans:property name="userDetailsService" ref="LoginServiceImpl"/&gt;
          &lt;beans:property name="passwordEncoder" ref="encoder"/&gt;
      &lt;/beans:bean&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p>LoginServiceImpl :</p>
  
  <pre><code>@Transactional
  @Service("userDetailsService")
  public class LoginServiceImpl implements UserDetailsService {
  
      @Autowired
      private PersonDAO personDAO;
  
      @Autowired
      private Assembler assembler;
  
      public LoginServiceImpl() {
      }
  
  @Override
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
          Person person = personDAO.findPersonByUsername(username.toLowerCase());
          if (person == null) {
              throw new UsernameNotFoundException("Wrong username or password");
          }
          return assembler.buildUserFromUserEntity(person);
      }
  }
  </code></pre>
  
  <p>Assembler :</p>
  
  <pre><code>@Service("assembler")
  public class Assembler {
      @Transactional(readOnly = true)
      User buildUserFromUserEntity(Person userEntity) {
          String username = userEntity.getUsername().toLowerCase();
          String password = userEntity.getPassword();
  
          boolean enabled = userEntity.isEnabled();
          boolean accountNonExpired = userEntity.isAccountNonExpired();
          boolean credentialsNonExpired = userEntity.isCredentialsNonExpired();
          boolean accountNonLocked = userEntity.isAccountNonLocked();
  
          Collection&lt;GrantedAuthority&gt; authorities = new ArrayList&lt;&gt;();
          authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
  
          return new User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
      }
  }
  </code></pre>
  
  <p>If there is any more information required, kindly let me know. Thank you.. :-)</p>