2

我正在使用Tomcat (7.0.34) 领域的基于表单的身份验证。我的问题如下所述。

我有signA.jsp这是一个受保护的页面。然后我有auth.jsp这是登录页面。

对应用程序的第一个请求转到signA.jsp,然后请求被重定向到auth.jsp(因为此时,用户未经过身份验证),用户可以在其中输入登录凭据并点击提交。Tomcat 以 j_security_check 的形式获取操作。一旦身份验证成功,如果没有错误,请求将返回到signA.jsp,后者将请求转发到应用程序主页home.jsp。这工作得很好。

如果身份验证失败,则请求转到errorA.jsp文件,该文件将请求重定向到signA.jsp以及作为 get 参数的 statusId,并且进一步将请求再次重定向到auth.jsp

现在,假设我在C.jsp页面上登录到应用程序并且会话超时,然后当我单击导航到应用程序的其他页面时,请求被重定向到auth.jsp这实际上很好. 但是再次尝试重新登录时,我发现请求转到了上一个登录会话中最后访问的页面,在这种情况下它是C.jsp。理想情况下,我希望请求通过登录后的第一个默认页面,即home.jsp,我将登录详细信息和会话中的其他详细信息保存在整个应用程序中使用。

知道可能是什么问题吗?如果您能为我提供解决此问题的解决方案,我们将不胜感激。

4

1 回答 1

0

我有类似的问题。挖了几个小时,想出了一些 hacky 解决方案。

在您的会话对象中(通过调用 .isNew() 等),您无法判断是否有超时,因为如果有超时,tomcat 领域将已经创建一个新会话。因此,您需要在成功登录时在会话中设置一个属性。

在受保护的网址上添加过滤器。不要忘记将其添加到 web.xml。假设您的登录 Servlet 在下面/protected/login,所有其他请求都将执行/protected/some_other_url

/protected/some_other_url如果您的属性为 null的请求,则表示发生了超时。

您可以省略path.startsWith检查您的过滤器 url 模式是否正确或登录 servlet 可能位于不同的前缀等下。您明白了。

public class TimeoutFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    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 path = request.getServletPath();

        // login after timeout occurred
        if (session != null && session.getAttribute(YOUR_ATTRIBUTE) == null && path.startsWith("/protected") && !path.equals("/protected/login")) {
            response.sendRedirect("/protected/YOUR_START_PAGE");
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
    }

}
于 2013-11-01T19:55:24.337 回答