Come implementare un filtro di login in JSF?

Vorrei bloccare l’accesso ad alcune pagine anche se l’utente conosce l’url di alcune pagine. Ad esempio, /localhost:8080/user/home.xhtml (è necessario eseguire prima il login) se non si è registrati, quindi redirect a /index.xhtml .

Come si fa in JSF? Ho letto su Google che è necessario un filtro, ma non so come farlo.

È necessario implementare la class javax.servlet.Filter , eseguire il lavoro desiderato nel metodo doFilter() e doFilter() su un pattern URL che copre le pagine con restrizioni, /user/* forse? All’interno di doFilter() è necessario verificare la presenza dell’utente connesso nella sessione in qualche modo. Inoltre, è necessario prendere in considerazione le richieste di ajax e di risorse JSF di JSF. Le richieste ajax JSF richiedono una risposta XML speciale per consentire a JavaScript di eseguire un reindirizzamento. Le richieste di risorse JSF devono essere saltate altrimenti la tua pagina di login non avrà più immagini CSS / JS /.

Supponendo di avere una pagina /login.xhtml che memorizza l’utente che ha effettuato l’accesso in un bean gestito JSF tramite externalContext.getSessionMap().put("user", user) , è ansible ottenerlo tramite session.getAttribute("user") il solito modo come di seguito:

 @WebFilter("/user/*") 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. } } // You need to override init() and destroy() as well, but they can be kept empty. } 

Inoltre, il filtro disabilita anche la cache del browser sulla pagina protetta, quindi il pulsante Indietro del browser non le visualizzerà più.

Nel caso in cui si utilizzi OmniFaces , la libreria di utilità JSF, il codice sopra riportato potrebbe essere ridotto come segue:

 @WebFilter("/user/*") public class AuthorizationFilter extends HttpFilter { @Override public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws ServletException, IOException { String loginURL = request.getContextPath() + "/login.xhtml"; boolean loggedIn = (session != null) && (session.getAttribute("user") != null); boolean loginRequest = request.getRequestURI().equals(loginURL); boolean resourceRequest = Servlets.isFacesResourceRequest(request); if (loggedIn || loginRequest || resourceRequest) { if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https://stackoverflow.com/q/4194207/157882 Servlets.setNoCacheHeaders(response); } chain.doFilter(request, response); // So, just continue request. } else { Servlets.facesRedirect(request, response, loginURL); } } } 

Guarda anche:

  • La nostra pagina wiki dei filtri Servlet
  • Come gestire l’autenticazione / authorization con gli utenti in un database?
  • Utilizzando JSF 2.0 / Facelets, c’è un modo per colbind un listener globale a tutte le chiamate AJAX?
  • Evita il pulsante Indietro sull’applicazione web JSF
  • JSF: come controllare l’accesso e i diritti in JSF?

Mentre è ovviamente legittimo utilizzare un semplice filtro Servlet, ci sono alternative come

  • Sicurezza di spring
  • Sicurezza Java EE
  • Apache Shiro