Как реализовать фильтр входа в систему в JSF?
Я хотел бы заблокировать доступ к какой-либо странице, даже если пользователь знает URL-адрес некоторых страниц. Например, /localhost:8080/user/home.xhtml
(сначала необходимо выполнить вход), если не зарегистрировано, затем перенаправить на /index.xhtml
,
Как это сделать в JSF? Я прочитал в Google, что нужен фильтр, но я не знаю, как это сделать.
2 ответа
Вам необходимо реализовать javax.servlet.Filter
класс, сделать желаемую работу в doFilter()
метод и отобразить его на шаблон URL, охватывающий ограниченные страницы, /user/*
может быть? Внутри doFilter()
Вы должны как-то проверить присутствие вошедшего в систему пользователя в сеансе. Кроме того, вам также необходимо принять во внимание запросы AJAX и ресурсов JSF. AJAX-запросы JSF требуют специального XML-ответа, чтобы JavaScript мог выполнить перенаправление. Запросы ресурсов JSF необходимо пропустить, иначе на вашей странице входа больше не будет CSS / JS / изображений.
Предполагая, что вы /login.xhtml
страница, которая сохраняет зарегистрированного пользователя в управляемом компоненте JSF через 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://stackru.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://stackru.com/q/4194207/157882
Servlets.setNoCacheHeaders(response);
}
chain.doFilter(request, response); // So, just continue request.
}
else {
Servlets.facesRedirect(request, response, loginURL);
}
}
}
Смотрите также:
- Наша страница с фильтрами сервлетов
- Как обрабатывать аутентификацию / авторизацию с пользователями в базе данных?
- Используя JSF 2.0 / Facelets, есть ли способ присоединить глобальный слушатель ко всем вызовам AJAX?
- Избегайте кнопки возврата в веб-приложении JSF
- JSF: Как контролировать доступ и права в JSF?
Хотя, конечно, законно использовать простой фильтр сервлетов, существуют альтернативы, такие как