Cómo redirigir a la página de acceso cuando la sesión ha caducado en aplicación web de Java?
Esta es una pregunta incorrecta. Debe diferenciar entre los casos "El usuario no ha iniciado sesión" y "La sesión ha expirado". Básicamente, desea redireccionar a la página de inicio de sesión cuando el usuario no está conectado. No cuando la sesión ha expirado. La respuesta actualmente aceptada solo marca HttpSession#isNew()
. Pero esto obviamente falla cuando el usuario ha enviado más de una solicitud en la misma sesión cuando la JSP crea implícitamente la sesión o no. P.ej. cuando solo presionas F5 en la página de inicio de sesión.
Como dije, en su lugar deberías verificar si el usuario está conectado o no. Dado el hecho de que está haciendo este tipo de preguntas mientras los marcos de autenticación estándar como j_security_check
, Shiro, Spring Security, etc. ya administran esto de forma transparente (y por lo tanto no habría necesidad de hacer este tipo de preguntas sobre ellos), eso solo puede significa que está utilizando un enfoque de autenticación de cosecha propia.
Suponiendo que usted está almacenando el usuario que ha iniciado sesión en la sesión de inicio de sesión en alguna servlet, como a continuación:
@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);
}
}
}
A continuación, puede comprobar que, en un inicio de sesión filter, como a continuación:
@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);
}
}
// ...
}
No hay necesidad de juguetear con los frágiles controles HttpSession#isNew()
.
Por qué no utilizar un SessionListener y redirigir en la sesión destruido? –
@Mr_and_Mrs_D: porque no hay necesariamente una solicitud HTTP disponible durante la destrucción de la sesión. – BalusC