2

我正在使用以下过滤器来控制对使用 GlassFish 作为应用程序服务器的 JSF 2.0 中所有页面的访问。问题是,使用此代码虽然过滤器工作正常,并且如果用户尝试直接访问任何其他页面,但 login.xhtml 看起来不太好(没有显示彩色图像并且页面形状发生变化),它应该被重定向到 log.xhtml是。但是,如果我删除 sendRedirect 语句并将其替换为 chain.doFilter 语句,则页面以相同的方式显示,因为它应该看起来不错,但是过滤显然不起作用。我该如何解决这个问题?

LoggingFilter.java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {   
    HttpServletRequest req = (HttpServletRequest) request;
    LoginBean auth = (LoginBean) req.getSession().getAttribute("loginBean");




    if ((auth != null && auth.isLoggedIn()) || req.getRequestURI().endsWith("/login.xhtml")) {
        // User is logged in, so just continue request.
        HttpServletResponse httpResponse = (HttpServletResponse)response;
        httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        httpResponse.setDateHeader("Expires", 0); // Proxies.
        chain.doFilter(request, response);
    } else {
        // User is not logged in, so redirect to index.
        HttpServletResponse res = (HttpServletResponse) response;
        res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
        //FacesContext.getCurrentInstance().getExternalContext().dispatch("/login.xhtml");
        //chain.doFilter(request, response);
    }
}
4

1 回答 1

9

此过滤器还将 CSS/JS/图像文件上的所有请求重定向到登录页面。浏览器最终得到一个响应,其中包含一些代表登录页面的 HTML 代码,而不是它请求的具体 CSS/JS/图像内容,因此浏览器无法应用必要的外观。

假设您 100% 使用 JSF 资源管理(<h:outputStylesheet>等),因此它们都被/javax.faces.resource/*URI 覆盖,请按如下方式重写您的过滤器:

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

    LoginBean auth = (session != null) ? session.getAttribute("loginBean") : null;
    String loginURL = request.getContextPath() + "/faces/login.xhtml";

    boolean loggedIn = auth != null && auth.isLoggedIn();
    boolean loginRequest = request.getRequestURI().equals(loginURL);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + "/faces" + ResourceHandler.RESOURCE_IDENTIFIER);

    if (loggedIn || loginRequest || resourceRequest)) {
        if (!resourceRequest) {
            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);
    } else {
        response.sendRedirect(loginURL);
    }
}

请注意,不应在资源请求上设置无缓存标头,否则您会破坏浏览器缓存对 CSS/JS/图像文件的好处。

于 2013-01-25T17:46:31.083 回答