La redirección de autorización en la caducidad de la sesión no funciona al enviar un formulario JSF, la página sigue siendo la misma

Estoy usando JSF2. Implementé un servlet de caras personalizado así:

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

en el que estoy haciendo algunas comprobaciones de autorización y enviando una redirección cuando el usuario no está conectado:

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

Esto funciona cuando el usuario intenta navegar a otra página. Sin embargo, esto no funciona cuando un formulario JSF es enviado por un enlace / botón de comando JSF. La línea línea sendRedirect() y se ejecuta, no se lanza ninguna excepción, pero el usuario permanece en la misma página. Básicamente, no hay ningún cambio visual en absoluto.

¿Por qué funciona esto en la navegación de página, pero no en el envío de formulario?

Su problema concreto probablemente se deba a que su enlace / botón de comando JSF está enviando una solicitud AJAX que a su vez espera una respuesta XML especial. Si está enviando un redireccionamiento como respuesta a una solicitud de ajax, entonces simplemente volvería a enviar la solicitud de ajax a esa URL. Esto a su vez falla sin comentarios porque la URL de redirección devuelve una página HTML completa en lugar de una respuesta XML especial. En realidad, debería devolver una respuesta XML especial en la que el motor JSF ajax recibe instrucciones para cambiar la window.location actual. window.location .

Pero en realidad tienes problemas mayores: usar la herramienta incorrecta para el trabajo. Debe usar un filtro de servlet para el trabajo, no un servlet nacional y seguramente no uno que suplante al FacesServlet que es el responsable de todos los trabajos de JSF.

Suponiendo que está realizando el inicio de sesión en un bean de respaldo JSF con solicitud / vista de ámbito como sigue (si usa autenticación administrada por contenedor, consulte también el segundo ejemplo de Realización de autenticación de usuario en Java EE / JSF usando j_security_check ):

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

Entonces este ejemplo inicial de un filtro debería hacer:

 @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. } } // ... } 

Ver también:

  • Usando JSF 2.0 / Facelets, ¿hay alguna manera de conectar un oyente global a todas las llamadas AJAX?
  • FullAjaxExceptionHandler no muestra la página de error de sesión expirada en el botón ajax

FacesContext.getCurrentInstance (). GetExternalContext (). Redirect (“newpage.xhtml”); prueba esto … en lugar de res.sendredirect (cpath).