如何在Java Web应用程序中会话过期时重定向到登录页面?

2022-08-31 23:55:56

我正在 JBoss AS 5 中运行一个 Web 应用程序。我还有一个 servlet 过滤器,它可以拦截对服务器的所有请求。现在,如果会话已过期,我想将用户重定向到登录页面。我需要在过滤器中执行此“isSessionExpired()”检查,并需要相应地重定向用户。我该怎么做?我在 web.xml 中设置会话时间限制,如下所示:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>

答案 1

您可以使用过滤器并执行以下测试:

HttpSession session = request.getSession(false);// don't create if it doesn't exist
if(session != null && !session.isNew()) {
    chain.doFilter(request, response);
} else {
    response.sendRedirect("/login.jsp");
}

上述代码未经测试

然而,这并不是最广泛的解决方案。您还应该测试会话中是否有某些特定于域的对象或标志可用,然后再假设由于会话不是新会话,用户必须已登录。请保持偏执


答案 2

如何在Java Web应用程序中会话过期时重定向到登录页面?

这是一个错误的问题。您应该区分“用户未登录”和“会话已过期”的情况。您基本上希望在用户未登录时重定向到登录页面。会话过期时不可以。当前接受的答案仅检查 。但是,当用户在同一会话中发送了多个请求时,当会话是由 JSP 隐式创建的,或者不是这样,这显然会失败。例如,只需在登录页面上按F5即可。HttpSession#isNew()

如前所述,您应该检查用户是否已登录。鉴于您正在问此类问题,而标准身份验证框架(如,Shiro,Spring Security等)已经透明地管理了这个问题(因此没有必要对它们提出此类问题),这只能意味着您正在使用自行开发的身份验证方法。j_security_check

假设您将会话中的登录用户存储在某个登录 servlet 中,如下所示:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user);
            response.sendRedirect(request.getContextPath() + "/home");
        } else {
            request.setAttribute("error", "Unknown login, try again");
            doGet(request, response);
        }
    }

}

然后,您可以在如下所示的登录过滤器中进行检查:

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

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

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

    // ...
}

无需摆弄脆性支票。HttpSession#isNew()


推荐