使用 Servlet 过滤器和 j_security_check 登录时出现无限循环

Posted

技术标签:

【中文标题】使用 Servlet 过滤器和 j_security_check 登录时出现无限循环【英文标题】:Endless loop when logging in with Servlet Filter and j_security_check 【发布时间】:2017-01-08 09:12:44 【问题描述】:

我已经实现了一个 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>

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

你只是通过反转条件来打破无限循环。【参考方案2】:

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

“重定向”是一个全新的请求。它向用户的浏览器发送一个响应,告诉它获取一个新的 URL;因此,该新请求将再次点击您的过滤器,一次又一次......一次又一次。

您可以测试请求的 URI 是否为“logon.html”,如果是,则只需“doFilter”,或者进行请求转发。

【讨论】:

以上是关于使用 Servlet 过滤器和 j_security_check 登录时出现无限循环的主要内容,如果未能解决你的问题,请参考以下文章

过滤器

Servlet过滤器基础及使用场景

[JavaWeb] Servlet Filter

我们可以使用过滤器代替 Servlet 吗?

如何使用保留请求正文和响应正文的 servlet 过滤器记录请求和响应?

寻找使用 servlet 过滤器将内容插入响应的示例