O redirecionamento de autorização na expiração da session não funciona no envio de um formulário JSF, a página permanece a mesma

Eu estou usando o JSF2. Eu implementei um servlet personalizado de faces da seguinte forma:

public class MyFacesServletWrapper extends MyFacesServlet { // ... } 

em que estou fazendo algumas verificações de autorização e enviando um redirecionamento quando o usuário não está logado:

 public void service(ServletRequest request, ServletResponse response) { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; if (...) { String loginURL = req.getContextPath() + "/LoginPage.faces"; res.sendRedirect(loginURL); } } 

Isso funciona quando o usuário tenta navegar para outra página. No entanto, isso não funciona quando um formulário JSF é enviado por um link / botão de comando do JSF. A linha sendRedirect() é atingida e executada, nenhuma exceção é lançada, mas o usuário permanece na mesma página. Basicamente, não há nenhuma mudança visual.

Por que isso funciona na navegação de página, mas não no envio de formulário?

Seu problema concreto é provavelmente causado porque o link / botão do comando JSF está realmente enviando uma solicitação ajax que, por sua vez, espera uma resposta XML especial. Se você estiver enviando um redirecionamento como resposta a uma solicitação de ajax, ele apenas enviaria novamente a solicitação ajax para essa URL. Isso, por sua vez, falha sem feedback porque a URL de redirecionamento retorna uma página HTML inteira em vez de uma resposta XML especial. Você deve, na verdade, estar retornando uma resposta XML especial em que o mecanismo JSF ajax foi instruído a alterar a window.location .

Mas você realmente tem problemas maiores: usar a ferramenta errada para o trabalho. Você deve usar um filtro de servlet para o trabalho, não um servlet FacesServlet e, com certeza, nenhum que substitua o FacesServlet que é o responsável por todos os trabalhos do JSF.

Supondo que você esteja executando o login em um bean de apoio do JSF com escopo de solicitação / visualização da seguinte maneira (se estiver usando autenticação gerenciada por contêiner, consulte também o segundo exemplo de Executando autenticação do usuário no Java EE / JSF usando j_security_check ):

 externalContext.getSessionMap().put("user", user); 

Então este exemplo de kickoff de um filtro deve fazer:

 @WebFilter("/*") // Or @WebFilter(servletNames={"facesServlet"}) public class AuthorizationFilter implements Filter { private static final String AJAX_REDIRECT_XML = "< ?xml version=\"1.0\" encoding=\"UTF-8\"?>" + ""; @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(false); String loginURL = request.getContextPath() + "/login.xhtml"; boolean loggedIn = (session != null) && (session.getAttribute("user") != null); boolean loginRequest = request.getRequestURI().equals(loginURL); boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/"); boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request")); if (loggedIn || loginRequest || resourceRequest)) { if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. response.setHeader("Pragma", "no-cache"); // HTTP 1.0. response.setDateHeader("Expires", 0); // Proxies. } chain.doFilter(request, response); // So, just continue request. } else if (ajaxRequest) { response.setContentType("text/xml"); response.setCharacterEncoding("UTF-8"); response.getWriter().printf(AJAX_REDIRECT_XML, loginURL); // So, return special XML response instructing JSF ajax to send a redirect. } else { response.sendRedirect(loginURL); // So, just perform standard synchronous redirect. } } // ... } 

Veja também:

  • Usando o JSF 2.0 / Facelets, existe uma maneira de append um ouvinte global a todas as chamadas do AJAX?
  • FullAjaxExceptionHandler não mostra a página de erro de expiração da session no botão ajax

FacesContext.getCurrentInstance (). GetExternalContext (). Redirect (“newpage.xhtml”); tente isso …. no lugar de res.sendredirect (cpath).