java - 如何制作过滤器以避免访问未记录的页面?

标签 java security jsf servlet-filters

所以我正在编写一个拦截器,这样当用户尝试在没有登录的情况下访问页面时,他就会被发送回登录页面 问题是,我的过滤器是检查用户是否登录的条件始终为真,最糟糕的是;它还拦截资源(css、图像、js) 那么我应该如何更改过滤器才能正常工作? 这是我的代码:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
     try {
        // check whether session variable is set
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        boolean estaLoggeado = false;
        if (req.getSession().getAttribute("estaLoggeado") != null) {
            estaLoggeado = new Boolean("" + req.getSession().getAttribute("estaLoggeado"));
        }
        //  allow user to proccede if url is login.xhtml or user logged in or user is accessing any page in //public folder
        String reqURI = req.getRequestURI();
        System.out.println(reqURI);
        System.out.println("index: " + reqURI.indexOf("/index.xhtml"));
        System.out.println("pages: " + reqURI.indexOf("/pages/"));
        System.out.println("resources: " + reqURI.contains("javax.faces.resource"));
        System.out.println("log: " + estaLoggeado);
        if ((reqURI.indexOf("/index.xhtml") >= 0 || reqURI.indexOf("/pages/") >= 0 || reqURI.contains("javax.faces.resource"))) {
            System.out.println("Si");
            chain.doFilter(request, response);
        } else {   // user didn't log in but asking for a page that is not allowed so take user to login page
            System.out.println("No");
            res.sendRedirect(req.getContextPath() + "/pages/index.xhtml");  // Anonymous user. Redirect to login page
        }
     } catch(Throwable t) {
        System.out.println(t.getMessage());
    }
} //doFilter

提前致谢!!

最佳答案

您忘记检查estaLoggeadoif()堵塞。换句话说,您永远不会真正检查用户是否已登录。您只是将用户是否已登录打印到标准输出。

总而言之,这个过滤器的逻辑相当笨拙。那些contains()对 URI 的检查非常差(请注意 indexOf(part) >= 0 实际上与 contains(part) 完全相同)。如果该部分位于 URL 的开头、中间或结尾怎么办?您应该执行精确/开始/结束匹配。

这里是重写:

@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() + "/pages/index.xhtml";

    boolean loggedIn = (session != null) && (session.getAttribute("estaLoggeado") != null);
    boolean loginRequest = request.getRequestURI().equals(loginURL);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");

    if (loggedIn || loginRequest || resourceRequest)) {
        chain.doFilter(request, response); // So, just continue request.
    }
    else {
        response.sendRedirect(loginURL); // So, redirect to login page.
    }
}

(作为旁注:我建议将 estaLoggeado 替换为 user (或 usuario 如果您确实需要使非英语人士无法阅读您的代码),以便它代表整个用户而不仅仅是一个无用的“标志”)

请注意,这不包括 ajax 请求。当提交 JSF ajax 表单期间 session 过期时,重定向将会失败,并且没有视觉反馈。对于更扩展的过滤器,请参阅以下答案:Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same .

关于java - 如何制作过滤器以避免访问未记录的页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19713773/

相关文章:

rest - 调用 REST 服务时 SSL 握手失败

git - 发布我的 .git 目录进行调试是否安全?

java - JSF:初始请求和回发请求?

java - Firestore执行复合查询,事件 "MODIFIED"未拦截

java - 如何分解一个数字并将其数字相乘?

java - 如何在使用 Spring Batch ItemWriter 写入文件时关闭分隔符

java - Spring Cloud Stream Kafka 记录太大

ios - 应用程序传输安全 : Which method for RESTful APIs? `NSExceptionAllowsInsecureHTTPLoads` 或 `NSAllowsArbitraryLoads`

java - 如何将 JSF 与自定义 servlet 集成?

Javascript 在基于 PrimeFaces 的页面中搞砸导航