Meu Post anterior foi fechado sem resposta, então vamos novamente …
Estou praticando meus estudos com desenvolvimento Web e tenho um problema após o Logout do Spring Security no meu projeto (JSF, Primefaces, Hibernate, Spring e Spring Security, Tomcat 7).
Depois de acionar o Link de sair na página, o Spring sai e redireciona para a página de Login novamente.
Mas se clicar no botão Voltar do navegador, da para ver o conteúdo das páginas anteriores.
Se clicar em qualquer botão ele devolve para a página de Login novamente indicando que a sessão já foi encerrada, mas ainda permite ver as páginas acessadas anteriormente.
Já coloquei as propriedades EXPIRES e PRAGMA na Tag META mas não funcionou.
Boa tarde @edulemos, obrigado pela dica, mas o problema ainda continua.
O meu logout estava no padrão do Spring. #{request.contextPath}/j_spring_security_logout
Mesmo depois que implementei o método de saída que sugeriu no meu ManagedBean, o logout continua funcionando certinho por ele também, mas ainda assim o Voltar do navegador deixa passar pelas páginas anteriores.
Ainda junto ao seu método coloquei mais algumas coisas para forçar como abaixo e nada.
Desabilitei o Cache da página na configuração da hospedagem também e nada.
O comportamento é o mesmo tanto no localhost de desenvolvimento quando no ambiente de produção do Datacenter.
Sim, conforme você mostrou e abaixo também, para invalidar uma sessão do JSF utiliza-se: FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
Obrigado @edulemos e @cviniciusm pelo apoio.
Tentei as soluções propostas por vocês e também não havia dado certo.
Mas pelo caminho delas achei o que precisava e agora está funcionando.
Até deixei de utilizar o logout customizado e voltei o original do Spring Security.
Dessa forma tive que implementar esse filtro que força o não armazenamento do chace do navegador.
Não sei porque, mas de alguma forma parece que essa mesma configuração que já tinha no head das páginas não estava funcionando pelo jeito. Até tirei de lá.
Meu filtro ficou assim:
@WebFilter("/*")
public class CacheFilter implements Filter{
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
httpResponse.setHeader("Cache-Control", "no-cache,no-store,must-revalidate"); // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Date hora = Calendar.getInstance().getTime();
System.out.println(sdf.format(hora) + " - Passou no CacheFilter");
chain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
Obviamente perdi performance porque sem o cache ele faz toda hora a requisição para o provedor.
Mas como a aplicação é pequena, vai atender o quesito de segurança.
Conforme for estudando mais, espero achar uma solução melhor mais para frente que não custe desempenho.
Os cursos de JavaSever Faces no Alura mostram como implementar autenticação utilizando MySQL e JSF Phase Listener. E funciona corretamente. Quando o usuário faz logon, o objeto desse usuário é salvo na sessão; antes de uma página ser exibida o phase listener verifica se o objeto do usuário existe, em caso afirmativo mostra a página, caso contrário mostra a página de login. Não adianta usar os botões de ir para a próxima página ou voltar.
E o Java EE provê “Container Managed Authentication” que facilita a autenticação e autorização.
Assim, suponho que você não esteja fazendo a integração correta de JSF com Spring Security.
Veja o projeto JoinFaces (ex-projeto JSF Spring Boot) que tem um exemplo que mostra a integração da JSF + Spring Boot + Spring Security, com autenticação e autorização.