有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何制作过滤器以避免在未登录的情况下访问页面?

所以我写了一个拦截器,当一个用户试图在没有登录的情况下访问一个页面时,他会被发送回登录 问题是,我的过滤器是,检查用户是否登录的条件总是正确的,最糟糕的是什么;它还拦截资源(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

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    你忘了在if()块中检查estaLoggeado。换句话说,你永远不会真正检查用户是否登录。你只是在打印用户是否登录

    总而言之,这个过滤器的逻辑相当笨拙。URI上的contains()检查非常糟糕(注意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.
        }
    }
    

    (作为旁注:我建议用user替换estaLoggeado(或者usuario,如果你真的需要让你的代码对非英国人来说不可读),这样它就代表了整个用户,而不仅仅是一个无用的“标志”)

    注意,这不包括ajax请求。当会话在提交JSF ajax表单期间过期时,重定向将失败,并且没有视觉反馈。要获得更广泛的过滤器,请点击以下答案:Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same