Il reindirizzamento dell’authorization alla scadenza della sessione non funziona all’invio di un modulo JSF, la pagina rimane invariata

Sto usando JSF2. Ho implementato un servlet di facce personalizzate in questo modo:

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

in cui sto facendo alcuni controlli di authorization e inviando un reindirizzamento quando l’utente non ha effettuato l’accesso:

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

Funziona quando l’utente prova a navigare verso un’altra pagina. Tuttavia, questo non funziona quando un modulo JSF viene inviato da un pulsante / pulsante di comando JSF. La linea sendRedirect() viene colpita ed eseguita, nessuna eccezione è stata lanciata, ma l’utente rimane nella stessa pagina. Fondamentalmente, non c’è alcun cambiamento visivo.

Perché funziona sulla navigazione della pagina, ma non sul modulo di invio?

Molto probabilmente il tuo problema concreto è causato dal fatto che il tuo link / pulsante di comando JSF sta effettivamente inviando una richiesta Ajax che a sua volta si aspetta una risposta XML speciale. Se invii un reindirizzamento come risposta a una richiesta Ajax, invierebbe nuovamente la richiesta Ajax a quell’URL. Questo a sua volta non funziona senza feedback perché l’URL di reindirizzamento restituisce un’intera pagina HTML anziché una speciale risposta XML. In realtà si dovrebbe restituire una risposta XML speciale in cui il motore ajax JSF è stato istruito per modificare l’attuale window.location .

Ma in realtà hai problemi più grandi: usare lo strumento sbagliato per il lavoro. Dovresti usare un filtro servlet per il lavoro, non un servlet di homegrown e sicuramente non uno che soppianta il FacesServlet che è il responsabile di tutto il JSF.

Supponendo che tu stia eseguendo l’accesso in una richiesta / vista il bean di supporto JSF come segue (se stai usando l’autenticazione gestita dal contenitore, vedi anche il 2 ° esempio di Esecuzione dell’autenticazione utente in Java EE / JSF usando j_security_check ):

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

Quindi questo esempio di kickoff di un filtro dovrebbe fare:

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

Guarda anche:

  • Utilizzando JSF 2.0 / Facelets, c’è un modo per colbind un listener globale a tutte le chiamate AJAX?
  • FullAjaxExceptionHandler non mostra la pagina di errore scaduta sessione sul pulsante Ajax

.. FacesContext.getCurrentInstance () getExternalContext () redirect ( “newpage.xhtml”); prova questo …. al posto di res.sendredirect (cpath).