O site que estou apoiando foi desenvolvido com Spring MVC (4.2.9.RELEASE), Spring Security (3.2.5.RELEASE), JSP, e Hibernate (4.3.8.Final). O frontend é um equilibrador de carga (Kemp LoadMaster 3000) e o local funciona em Tomcat (8.5.54). A fim de encontrar a causa deste problema, estou rodando apenas uma instância Tomcat atrás do balanceador de carga para ter um sistema mais simples. Cada página do site (páginas públicas e as páginas vistas após a autenticação) corre sob HTTPS.
O seguinte código simplificado mostra como demonstrar o problema:
@RequestMapping(value=/form, method = RequestMethod.GET)
public String surveyPageGet(HttpServletRequest request,
HttpServletResponse response,
Model model, Map<String, Object> map) throws IOException {
request.getSession().setAttribute(token, token-value);
System.out.println(request.getSession().getId());
return myform;
}
@RequestMapping(value=/form, method = RequestMethod.POST)
public String surveyPageGet(HttpServletRequest request,
HttpServletResponse response,
Model model, Map<String, Object> map) throws IOException {
System.out.println(request.getSession().getAttribute(token));
System.out.println(request.getSession().getId());
return redirect:/success;
}
O tempo limite da sessão no equilibrador de carga é de 60 minutos e seu modo persistente é
Super HTTP and Source IP
O tempo limite da sessão no Tomcat também é de 60 minutos especificado em web.xml
<session-config>
<session-timeout>60</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
O seguinte é a configuração relacionada na Spring Security.
<security:http auto-config=false use-expressions=true request-matcher=regex entry-point-ref=authenticationEntryPoint >
<security:intercept-url pattern=^\/secure\/.*$ access=hasRole('ROLE_USER') />
<security:access-denied-handler ref=accessDeniedHandler />
<security:logout invalidate-session=true logout-url=/secure/logout logout-success-url=/ delete-cookies=JSESSIONID />
<security:custom-filter ref=authenticationFilter position=FORM_LOGIN_FILTER />
<security:anonymous username=guest granted-authority=ROLE_GUEST />
</security:http>
Aqui estão as minhas observações sobre o ID da sessão e os dados da sessão no método POST. Para uma grande porcentagem do tempo, o método POST imprime o mesmo ID de sessão e valor simbólico se a submissão ocorrer dentro de 60 minutos após o formulário ser exibido. Isto é compreensível. O que eu não entendo é que para uma porcentagem muito pequena de casos em que a submissão do formulário acontece antes do limite de 60 minutos, o ID da sessão muda E o valor do token é nulo ou o ID da sessão permanece o mesmo MAS o valor do token é nulo
Como posso evitar que a identificação da sessão seja alterada e que os dados da sessão sejam perdidos se uma sessão não se prolongar? Eu realmente preciso disso por causa de como o site funciona. Eu gasto muito tempo online para uma possível correção e fiz muitos e vários testes (incluindo adicionar código para excluir a possibilidade de que o problema seja causado por spam ou ataque), mas sem sucesso
Por favor, sinta-se à vontade para me avisar se precisar de mais informações sobre o site.