Comment implémenter un filtre de connexion dans JSF?

je voudrais bloquer l'accès d'une page même si l'utilisateur connaît l'url de certaines pages. Par exemple, /localhost:8080/user/home.xhtml (besoin de faire la connexion en premier) si non connecté, redirigez vers /index.xhtml .

comment ça se fait dans JSF ? J'ai lu dans le Google qu'il fallait un filtre, mais je ne sais pas comment faire.

43
demandé sur BalusC 2011-12-12 23:58:57
la source

2 ответов

vous devez implémenter la classe javax.servlet.Filter , faire le travail désiré dans la méthode doFilter() et le cartographier sur un motif D'URL couvrant les pages restreintes, /user/* peut-être? À l'intérieur du doFilter() vous devez vérifier la présence de l'utilisateur connecté dans la session d'une manière ou d'une autre. En outre, vous devez également prendre en compte JSF ajax et les demandes de ressources. Les requêtes ajax de JSF nécessitent une réponse XML spéciale pour permettre à JavaScript d'effectuer une redirection. Demandes de ressources du JSF besoin de sauter sinon votre page de connexion n'aura plus de CSS/JS/images.

en supposant que vous avez une page /login.xhtml qui stocke l'utilisateur connecté dans un fichier géré par JSF via externalContext.getSessionMap().put("user", user) , alors vous pouvez l'obtenir via session.getAttribute("user") de la manière habituelle comme ci-dessous:

@WebFilter("/user/*")
public class AuthorizationFilter implements Filter {

    private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";

    @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 /q/prevent-user-from-seeing-previously-visited-secured-page-after-logout-39436/"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.
}

en outre, le filtre a également désactivé la mémoire cache du navigateur sur la page sécurisée, de sorte que le bouton de retour du navigateur ne les affichera plus.

dans le cas il se trouve que vous utilisez la bibliothèque utilitaire JSF OmniFaces , le code ci-dessus pourrait être réduit comme suit:

    @WebFilter ("/user/*")
public class AuthorizationFilter extends HttpFilter {

    @Remplacer
    public void doFilter (HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) lance ServletException, IOException {
        String loginURL = request.getContextPath () + "/login.xhtml";

        booléen loggedIn = (session != null) & & & (session.getAttribute ("utilisateur")!= NULL);
        boolean loginRequest = request.getRequestURI ().equals(loginURL);
        boolean resourceRequest = Servlets.isFacesResourceRequest (request);

        si (loggedIn | / loginRequest | / resourceRequest) {
            si (!resourceRequest) {//empêcher le navigateur de mettre en cache les ressources restreintes. Voir aussi /q/prevent-user-from-seeing-previously-visited-secured-page-after-logout-39436/"https://stackoverflow.com/tags/servlet-filters/info">notre Servlet Filters wiki page       
  
  • Comment gérer l'authentification/autorisation avec les utilisateurs dans une base de données?
  • en utilisant JSF 2.0 / Facelets, y a-t-il un moyen d'attacher un écouteur global à tous les appels AJAX?
  • éviter retour bouton sur l'application web de JSF
  • JSF: Comment contrôler l'accès et les droits dans JSF?
  • 88
    répondu BalusC 2017-09-21 23:28:07
    la source

    bien qu'il soit bien sûr légitime d'utiliser un simple filtre à Servlet, il existe des alternatives comme

    2
    répondu Werner Keil 2017-12-13 17:18:18
    la source