2016-03-07 42 views
-1

我正在開發一個在Tomcat上運行的Spring-MVC項目,其中我擁有用於​​身份驗證和授權的Spring-security。由於我們的項目目前正在開發中,我們有比平常更多的部署。通常,部署之後發生的情況是所有客戶端都在服務器重新啓動時註銷。Spring-security:即使在JVM重啓後也維護活動會話

有什麼辦法,我可以把會話數據的數據庫或其他地方,所以即使之後的Tomcat/JVM崩潰/重新啓動,已登錄的用戶不會有問題。

有沒有解決這個問題的策略?任何想法如何?

安全的applicationContext.xml:

<!-- Global Security settings --> 
    <security:http pattern="/resources/template/demo/clients" security="none"/> 

    <security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true"> 
     <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"/> 
     <security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService" 
           token-validity-seconds="1209600" data-source-ref="dataSource"/> 
     <security:logout delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout"/> 
    <!--<security:intercept-url pattern="/**" requires-channel="https"/>--> 
     <security:port-mappings> 
      <security:port-mapping http="80" https="443"/> 
     </security:port-mappings> 
     <security:logout logout-url="/logout" logout-success-url="/" success-handler-ref="myLogoutHandler"/> 

     <security:session-management session-fixation-protection="migrateSession"> 
      <security:concurrency-control session-registry-ref="sessionReg" max-sessions="5" expired-url="/login"/> 
     </security:session-management> 
    </security:http> 

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

    <beans:bean id="rememberMeAuthenticationProvider" 
       class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices"> 
     <beans:constructor-arg index="0" value="_spring_security_remember_me"/> 
     <beans:constructor-arg index="1" ref="userDetailsService"/> 
     <beans:constructor-arg index="2" ref="jdbcTokenRepository"/> 
     <property name="alwaysRemember" value="true"/> 
    </beans:bean> 

    <beans:bean id="jdbcTokenRepository" 
       class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"> 
     <beans:property name="createTableOnStartup" value="false"/> 
     <beans:property name="dataSource" ref="dataSource"/> 
    </beans:bean> 

    <!-- Remember me ends here --> 
    <security:authentication-manager alias="authenticationManager"> 
     <security:authentication-provider user-service-ref="LoginServiceImpl"> 
      <security:password-encoder ref="encoder"/> 
     </security:authentication-provider> 
    </security:authentication-manager> 

    <beans:bean id="encoder" 
       class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
     <beans:constructor-arg name="strength" value="11"/> 
    </beans:bean> 

    <beans:bean id="daoAuthenticationProvider" 
       class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
     <beans:property name="userDetailsService" ref="LoginServiceImpl"/> 
     <beans:property name="passwordEncoder" ref="encoder"/> 
    </beans:bean> 
</beans> 

LoginServiceImpl:

@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); 
    } 
} 

彙編:

@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<GrantedAuthority> authorities = new ArrayList<>(); 
     authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 

     return new User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); 
    } 
} 

如果有任何需要了解更多信息,請讓我知道。謝謝。:-)

+0

爲什麼這個問題被低估?任何解釋? –

+0

看看這個問題和答案的想法:http://stackoverflow.com/questions/13211615/how-to-store-spring-security-session-information-in-redis – Fortunato

+0

@Fortunato:Redis的選項執行的聲音好。我已經具備了記憶功能,正如鏈接所言,與Redis的Spring會話已經開箱即用。任何想法,我必須改變這個項目的正確整合? –

回答

0

不知道在春季可配置的,但是這是可能的Tomcat的(你提到使用Tomcat)。

在你的context.xml文件,找到這一行/語句

<Manager pathname="" /> 

評論/刪除此日誌。這將在優雅的tomcat重啓之間啓用會話持久性。

+0

該條目已被評論。 –

相關問題