如何在JSF中实现登录过滤器?

如何在JSF中实现登录过滤器?,jsf,jsf-2,login,authorization,servlet-filters,Jsf,Jsf 2,Login,Authorization,Servlet Filters,我想阻止某些页面的访问,即使用户知道某些页面的url。 例如,/localhost:8080/user/home.xhtml(需要先登录),如果未登录,则重定向到/index.xhtml 如何在JSF中实现这一点?我在谷歌上读到需要一个过滤器,但我不知道怎么做。你需要实现这个类,在doFilter()方法中完成所需的工作,并将其映射到覆盖受限页面的URL模式上,/user/*也许?在doFilter()中,您应该以某种方式检查登录用户是否存在于会话中。此外,还需要考虑JSF ajax和资源请求。

我想阻止某些页面的访问,即使用户知道某些页面的url。 例如,
/localhost:8080/user/home.xhtml
(需要先登录),如果未登录,则重定向到
/index.xhtml

如何在JSF中实现这一点?我在谷歌上读到需要一个过滤器,但我不知道怎么做。

你需要实现这个类,在
doFilter()
方法中完成所需的工作,并将其映射到覆盖受限页面的URL模式上,
/user/*
也许?在
doFilter()
中,您应该以某种方式检查登录用户是否存在于会话中。此外,还需要考虑JSF ajax和资源请求。JSF ajax请求需要一个特殊的XML响应,以便JavaScript执行重定向。需要跳过JSF资源请求,否则您的登录页面将不再有任何CSS/JS/图像

假设您有一个
/login.xhtml
页面,该页面通过
externalContext.getSessionMap().put(“user”,user)
将登录用户存储在JSF托管bean中,然后您可以通过
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.
}
另见:

    • 虽然使用简单的Servlet过滤器当然是合法的,但也有类似的选择


      是否可以使用@ManagedProperty(value=“#{auth}”)private auth auth,而不是使用getAttribute(“auth”)@杰克:错了
      @ManagedProperty
      仅在
      @ManagedBean
      中工作,而不是在
      @WebFilter
      @Jake:如果您使用的是CDI的
      @Named
      ,那么您可以使用
      @Inject
      将其注入
      @ManagedBean
      (或另一个
      @Named
      )还有一个
      @WebFilter
      @BalusC:在这种技术中,我们需要担心线程安全吗?@BalusC如果filter映射到
      /user/*
      ,并且登录页面位于
      /login.xhtml
      ,我想登录请求不会被捕获。登录页面应该位于
      /user/Login.xhtml
      ,但是我问自己:为什么我们需要保护登录页面?
      @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);
              }
          }
      
      }