使用 Servlet Filter 和 j_security_check 登录时无限循环

Endless loop when logging in with Servlet Filter and j_security_check

我已经实现了一个 servletFilter 并在我的 web.xml 中声明了它,但问题是我现在无法登录。用户提交他们的用户名和密码,代码重定向到 j_security_check 页面,然后无休止地重新加载 logon.html。在代码 doFilter(req,res) 中两次都被命中,用于发送回 logon.html 的 sendRedirect 代码从未被使用。

我还缺少其他元素吗?我读过 servlet 过滤器和 j_security_check 并不总是很好,但我想我可以找到解决方法。

代码:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);

    String loginURI = request.getContextPath() + "/logon.html";
    String securityURI = request.getContextPath() + "/j_security_check";

    boolean loggedIn = session != null && session.getAttribute("user") != null;
    boolean securityRequest = request.getRequestURI().equals(securityURI);
    boolean loginRequest = request.getRequestURI().equals(loginURI);

    if (loggedIn || loginRequest || securityRequest) {
        chain.doFilter(req, res);
    } else {
        response.sendRedirect(loginURI);
    }
}

因此代码会检查请求是来自登录页面还是 j_security_check 页面,如果是则处理 doFilter。这是有效的,但我不确定如果它两次都通过了,为什么它没有处理到应用程序?

web.xml:

<session-config>
    <session-timeout>1</session-timeout>
</session-config>

<filter>
    <filter-name>servletFilter</filter-name>
    <filter-class>org.t.s.w.AuthServletFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>servletFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

尝试像这样在过滤器中反转您的条件。

if (!loggedIn || !loginRequest || !securityRequest) {
    response.sendRedirect(loginURI);
} else {
    chain.doFilter(req, res);
}

问题很简单。您的过滤器链正在捕获所有请求,包括 logon.html 的请求。当过滤器发现用户未登录时,它会重定向到 "logon.html"。

A "redirect" 是一个全新的请求。它向用户的浏览器发送一个响应,告诉它获取一个新的 URL;因此,这个新请求将一次又一次地击中您的过滤器。

您可以测试请求的 URI 是否为 "logon.html",如果是 "doFilter",或者转发请求。