Java Filter无限循环

czu*_*upe 2 java authentication servlets infinite-loop servlet-filters

我想实现一个过滤器来进行身份验证,但不知何故,它被卡在无限循环中...任何想法都赞赏.

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    doBeforeProcessing(request, response);

    Throwable problem = null;
    HttpSession session = httpRequest.getSession(true);
    if(session.getAttribute("userName")!=null&&session.getAttribute("userName")!=(""))
    {
        try {
            chain.doFilter(request, response);
        } catch (Throwable t) {
            // If an exception is thrown somewhere down the filter chain,
            // we still want to execute our after processing, and then
            // rethrow the problem after that.
            problem = t;
            t.printStackTrace();
        }   
    }else{
        httpResponse.sendRedirect("login.jsp");
        return;
    }
Run Code Online (Sandbox Code Playgroud)

这个代码在调试模式下运行无限次,基本上我想在用户没有登录时将用户重定向到login.jsp.任何答案都可以.

Bal*_*usC 10

这里,

httpResponse.sendRedirect("login.jsp");
Run Code Online (Sandbox Code Playgroud)

您正在为目标页面发送新的 HTTP请求,而不是使用当前请求.如果新的HTTP请求被映射到过于通用的URL模式,例如/*.并且将执行相同的检查,并且将再次重定向.等等.这是一个无休止的故事.

FilterChain#doFilter()当前请求的页面是登录页面时,您还需要添加额外的检查以执行.

String loginURL = httpRequest.getContextPath() + "/login.jsp";

if (httpRequest.getRequestURI().equals(loginURL)) || session.getAttribute("userName") != null) {
    chain.doFilter(request, response);
} else {
    httpResponse.sendRedirect(loginURL);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我还删除了对空字符串的无意义检查作为用户名(但是,确保您的代码无法将空字符串设置为用户名.只是用于null表示未登录的用户.还请注意我修复了也重定向URL,因为当当前请求的URL位于子文件夹中时它会失败.

一种不同的方法是把在一个共同的子文件夹中的所有那些受限制的页面,如/app,/secured,/restricted等,并然后映射滤波器上的URL模式/app/*,/secured/*,/restricted/*等代替.如果将登录页面保留在此文件夹之外,则在请求登录页面时不会调用过滤器.


dou*_*arp 5

问题是您的过滤器正在运行login.jsp,当用户未登录时将反复重定向到自身.因为在过滤器上没有排斥语法url-pattern,你需要检测你的过滤器的URL,而忽略重定向,如果你已经在上login.jsp页:

    // your auth code
} else {
    String redirect = httpRequest.getContextPath() + "/login.jsp";
    String uri = httpRequest.getRequestURI().toString();
    if (uri.endsWith(redirect)){
        // URI ends with login.jsp, just process the chain
        chain.doFilter();
    } else {
        // not on the login page and not logged in, redirect
        httpResponse.sendRedirect(redirect);
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)