Endless loop when logging in with Servlet Filter and j_security_check

时间:2016-08-31 17:12:22

标签: java tomcat servlet-filters j-security-check

I have implemented a servletFilter and declared it in my web.xml but the issue is I cant login now. The user submits their username and password and the code redirects to a j_security_check page and then reloads logon.html again endlessly. In the code doFilter(req,res) is hit both times, the sendRedirect code used to send back to logon.html is never used.

Is there another element im missing? Ive read that servlet filters and j_security_check dont always play nice but I thought I could find a work around.

code:

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

so the code checks if the request is coming from the logon page or the j_security_check page and processes doFilter if they are. This is working but im not sure why its not processing through to the application if its passing both times?

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>

2 个答案:

答案 0 :(得分:1)

Try reversing your condition in the filter like this.

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

答案 1 :(得分:1)

The problem is pretty straight forward. Your filter chain is catching ALL requests, including a request for logon.html. When the filter discovers the user is not logged on, it redirects to "logon.html".

A "redirect" is a completely new request. It sends a response to the user's browser telling it to GET a new URL; therefore, that new request will hit your filter again, and again... and again.

You could test if the requested URI is "logon.html", and if so simply "doFilter", or perhaps do a request forward.