Подтвердить что ты не робот

Как реализовать фильтр входа в JSF?

Я хотел бы заблокировать доступ к какой-либо странице, даже если пользователь знает URL-адрес некоторых страниц. Например, /localhost:8080/user/home.xhtml (нужно сначала выполнить вход), если не зарегистрирован, а затем перенаправить на /index.xhtml.

Как это делается в JSF? Я читал в Google, что нужен фильтр, но я не знаю, как это сделать.

4b9b3361

Ответ 1

Вам необходимо реализовать класс javax.servlet.Filter, выполнить задание в методе doFilter() и нанести его на шаблон URL-адреса, охватывающий возможно, ограниченные страницы, /user/*? Внутри doFilter() вы должны проверить присутствие зарегистрированного пользователя в сеансе. Кроме того, вам также необходимо учитывать JAF ajax и запросы ресурсов. Запросы ajax JSF требуют специального ответа XML, чтобы JavaScript выполнял перенаправление. Запросы ресурсов JSF должны быть пропущены, иначе ваша страница входа не будет иметь никаких CSS/JS/изображений.

Предполагая, что у вас есть страница /login.xhtml, которая хранит зарегистрированного пользователя в управляемом JSF bean через externalContext.getSessionMap().put("user", user), вы можете получить его через session.getAttribute("user") обычным способом, как показано ниже:

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

Кроме того, фильтр также отключил кеш браузера на защищенной странице, поэтому кнопка назад браузера больше не отобразит их.

Если вы используете библиотеку служебных программ JSF OmniFaces, код выше можно уменьшить, как показано ниже:

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

}

См. также: