Samstag, Juni 6, 2020

Wie implementieren Sie ein login-filter in JSF?

Ich würde gerne blockieren, den Zugang von einer Seite, selbst wenn der Benutzer kennt die url von einigen Seiten.
Zum Beispiel /localhost:8080/user/home.xhtml (müssen sich zunächst anmelden), wenn nicht angemeldet, dann redirect zu /index.xhtml.

Wie dies in JSF ? Ich habe gelesen im Google, dass benötigt einen filter, aber ich weiß nicht, wie das zu tun.

InformationsquelleAutor Valter Silva | 2011-12-12

2 Kommentare

  1. 91

    Sie implementieren müssen, um die javax.- servlet.- Filter Klasse, führen die gewünschte Arbeit in doFilter() – Methode und ordnen Sie Sie auf ein URL-Muster für die Seiten beschränkt, /user/* vielleicht? Innerhalb der doFilter() Sie sollten überprüfen, die Anwesenheit der angemeldeten Benutzer in der Sitzung irgendwie. Weiter müssen Sie auch nehmen, JSF, ajax-und Ressourcen-Anforderungen zu berücksichtigen. JSF-ajax-Anforderungen erfordern eine spezielle XML-Antwort lassen Sie JavaScript eine Umleitung durchzuführen. JSF-Ressource-Anforderungen müssen übersprungen werden, ansonsten wird Ihr login-Seite keine CSS/JS/Bilder mehr.

    Vorausgesetzt, Sie haben eine /login.xhtml Seite, welche den angemeldeten Benutzer in eine JSF managed bean über externalContext.getSessionMap().put("user", user), dann konnte man es über session.getAttribute("user") der üblichen Weise wie folgt:

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

    Darüber hinaus werden die filter auch deaktiviert, browser cache auf sicheren Seite, also die zurück-Schaltfläche Ihres Browsers wird nicht zeigen, bis Sie nicht mehr.

    In den Fall, Sie geschehen, JSF verwenden utility library OmniFaces, obige code könnte reduziert werden, wie unten:

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

    Siehe auch:

    Es funktioniert perfekt, mein Freund, vielen Dank! Dieser Weg ist sogar noch besser, weil ich nicht zu ändern web.xml =]
    Du bist herzlich willkommen.
    anstelle der Verwendung von getAttribute(„auth“), könntest du mit @ManagedProperty(value=“#{auth}“) private Auth auth;
    Falsch. @ManagedProperty arbeitet in einem @ManagedBean nur, nicht in eine @WebFilter.
    Wenn Sie mit den CDI ‚ s @Named statt, dann können Sie @Inject zu injizieren und es in beiden einen @ManagedBean (oder nur ein weiterer @Named) und eine @WebFilter.

    InformationsquelleAutor BalusC

Kostenlose Online-Tests