3

我想实现一个过滤器来进行身份验证,但不知何故它陷入了无限循环......任何想法都值得赞赏。

    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;
    }

调试模式下的这段代码只是无限次运行,基本上我想在用户未登录时将用户重定向到 login.jsp。任何答案表示赞赏。

4

2 回答 2

10

这里,

httpResponse.sendRedirect("login.jsp");

您正在为目标页面发送的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);
}

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

另一种选择是将所有这些受限页面放在一个公共子文件夹中,例如/app, /secured,/restricted等,然后将过滤器映射到 , , 等的 URL/app/*模式/secured/*/restricted/*。如果您将登录页面保留在此文件夹之外,则在请求登录页面时不会调用过滤器。

于 2012-10-29T01:22:38.780 回答
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;
    }
}
于 2012-10-29T01:23:20.863 回答