tutorial example ejemplo spring spring-mvc spring-security logout jsessionid

example - spring security maven



El cierre de sesión deja JSESSIONID en el navegador. ¿Cómo borrarlo? (6)

Estoy utilizando el siguiente código para desconectar a un usuario de mi sistema.

/** * This function helps to set the session attribute for the present user to null and then * removes the attribute itself and this helps in clearing the session * @param request * @param response */ @RequestMapping(value = AuthConstants.EXIT, method = RequestMethod.POST) public void exitPrime(HttpServletRequest request, HttpServletResponse response) { /*Getting session and then invalidating it*/ HttpSession session = request.getSession(false); if(request.isRequestedSessionIdValid() && session != null) { session.invalidate(); } }

Esto conduce a un cierre de sesión exitoso, pero la ID de JSESSION dada por el inicio de sesión aún permanece en el navegador debido a que para cualquier usuario nuevo se usa nuevamente la misma ID de JSESSION al iniciar sesión. Quiero que la cookie JSESSIONID sea válida solo para la sesión actual y una vez que el usuario cierre la sesión, debería ser destruida o inválida para el inicio de sesión que se realizará la próxima vez. Mi código de inicio de sesión es el siguiente:

/** * This method allows one to log into the system and generates a token for a valid employee. * @param authRequest * @param request * @param response * @return */ @RequestMapping(value = AuthConstants.ENTRY, method = RequestMethod.POST, consumes = ApplicationConstants.APPLICATION_JSON) public @ResponseBody AuthResponse primeEntry(@RequestBody AuthRequest authRequest,HttpServletRequest request, HttpServletResponse response) { AuthResponse authResponse = new AuthResponse(); if(authRequest != null && authRequest.getEmployeeAuth().getEmployeeNumber() != null && !authRequest.getEmployeeAuth().getEmployeeNumber().isEmpty()){ /*To check whether the user is valid*/ String employeeNumber = authRequest.getEmployeeAuth().getEmployeeNumber(); UserBean userBean = new UserBean(); userBean = userService.getUser(employeeNumber); if(userBean != null) { HttpSession session = request.getSession(true); session.setAttribute("user", userBean); setAuthResponseSuccess(authResponse); }else{ /*If user does not exist the too throw error 500*/ setAuthResponseFailure(authResponse); } }else{ /*If input JSON is not valid then throw error 500*/ setAuthResponseFailure(authResponse); } return authResponse; }

Estoy usando Spring 3.2 y quiero hacer Iniciar sesión y Cerrar sesión manualmente. Por favor ayuda.

Código de clase completo

@Controller @RequestMapping(value = "/auth") public class AuthController { @Autowired HttpServletRequest request; @Autowired HttpSession session; @Autowired IUserService userService; /** * This method allows one to log into the system and generates a token for a valid employee. * @param authRequest * @param request * @param response * @return */ @RequestMapping(value = AuthConstants.ENTRY, method = RequestMethod.POST, consumes = ApplicationConstants.APPLICATION_JSON) public @ResponseBody AuthResponse primeEntry(@RequestBody AuthRequest authRequest,HttpServletRequest request, HttpServletResponse response) { AuthResponse authResponse = new AuthResponse(); if(authRequest != null && authRequest.getEmployeeAuth().getEmployeeNumber() != null && !authRequest.getEmployeeAuth().getEmployeeNumber().isEmpty()){ /*To check whether the user is valid*/ String employeeNumber = authRequest.getEmployeeAuth().getEmployeeNumber(); UserBean userBean = new UserBean(); userBean = userService.getUser(employeeNumber); if(userBean != null) { HttpSession session = request.getSession(true); session.setAttribute("user", userBean); setAuthResponseSuccess(authResponse); }else{ /*If user does not exist the too throw error 500*/ setAuthResponseFailure(authResponse); } }else{ /*If input JSON is not valid then throw error 500*/ setAuthResponseFailure(authResponse); } return authResponse; } /** * This function helps to set the session attribute for the present user to null and then * removes the attribute itself and this helps in clearing the session * @param request * @param response */ @RequestMapping(value = AuthConstants.EXIT, method = RequestMethod.POST) public void exitPrime(HttpServletRequest request, HttpServletResponse response) { /*Getting session and then invalidating it*/ HttpSession session = request.getSession(false); if(request.isRequestedSessionIdValid() && session != null) { session.invalidate(); } } private AuthResponse setAuthResponseFailure(AuthResponse authResponse) { authResponse.setResponseCode(ApplicationConstants.INTERNAL_ERROR_CODE); authResponse.setStatus(StatusType.FAILURE); authResponse.setResponseMsg(ApplicationConstants.INTERNAL_ERROR_MESSAGE); return authResponse; } private AuthResponse setAuthResponseSuccess(AuthResponse authResponse){ authResponse.setResponseCode(ApplicationConstants.OK); authResponse.setStatus(StatusType.SUCCESS); authResponse.setResponseMsg(ApplicationConstants.LOGIN_SUCCESS); return authResponse; } }


Después de experimentar un poco, llegué a la conclusión de que si desea que el valor de la cookie del navegador persista, no haga nada y el código anterior funcionará bien para usted. Por otro lado si quieres la salida de la cookie algo como

Set-Cookie: JSESSIONID=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/

Luego puedes tomar este fragmento de código y probarlo.

private void handleLogOutResponseCookie(HttpServletResponse response) { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { cookie.setMaxAge(0); cookie.setValue(null); cookie.setPath("/"); response.addCookie(cookie); }

Esto resolvería el problema y destruiría la cookie al cerrar la sesión.


El enfoque listado anteriormente no funcionó para mí, pero con algunas modificaciones funcionó, aunque solo hice pruebas limitadas, así que YMMV.

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session = req.getSession(false); if (session != null) { String sessionId = session.getId(); session.invalidate(); Cookie[] cookies = req.getCookies(); for (Cookie cookie : cookies) { if (sessionId.equalsIgnoreCase(cookie.getValue())) { cookie.setMaxAge(0); cookie.setValue(null); cookie.setDomain(req.getServerName()); cookie.setPath(req.getServletContext().getContextPath() + "/"); cookie.setSecure(req.isSecure()); res.addCookie(cookie); break; } } } }


No estoy seguro de si aún es real, pero se puede extender LogoutFilter de esta manera para especificar los pasos exactos que se realizarán en el cierre de sesión, incluida la invalidación de cookies personalizadas.

<beans:bean id="sessionInvalidationFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <beans:property name="filterProcessesUrl" value="/logout"/> <beans:constructor-arg> <beans:array> <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> <beans:bean class="org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler"> <beans:constructor-arg value="JSESSIONID"/> </beans:bean> </beans:array> </beans:constructor-arg> </beans:bean>


No hay nada de malo con las sobras de JSESSIONID en su navegador siempre y cuando ya no sea válido. JSESSIONID es solo un grupo de caracteres aleatorios que no contienen sus datos reales.

Sin embargo, sospecho que su problema es que usó la anotación @SessionAttributes a nivel de clase, y trató de session.invalidate() . Con este escenario después de que se invalide la sesión anterior, Spring crea automáticamente una nueva sesión (y JSESSIONID) para usted porque tiene que persistir atributos de modelo especificados en la sesión.

Para IMO, un mejor enfoque es crear un nuevo controlador que no tenga @SessionAttributes e invalidar su sesión desde allí.


Tomcat agrega una barra al final de la ruta de contexto. Ahora, cuando establece el atributo de eliminación de cookie, Spring intenta encontrar la cookie para la ruta sin una barra al final. Debido a que no lo encuentra, la cookie no se eliminará, lo que dará como resultado la visualización de la página de vencimiento de la sesión en lugar de la página de inicio de sesión.

La solución siguiente hará el truco.

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) { Cookie cookieWithSlash = new Cookie("JSESSIONID", null); //Tomcat adds extra slash at the end of context path (e.g. "/foo/") cookieWithSlash.setPath(request.getContextPath() + "/"); cookieWithSlash.setMaxAge(0); Cookie cookieWithoutSlash = new Cookie("JSESSIONID", null); //JBoss doesn''t add extra slash at the end of context path (e.g. "/foo") cookieWithoutSlash.setPath(request.getContextPath()); cookieWithoutSlash.setMaxAge(0); //Remove cookies on logout so that invalidSessionURL (session timeout) is not displayed on proper logout event response.addCookie(cookieWithSlash); //For Tomcat response.addCookie(cookieWithoutSlash); //For JBoss }


Una forma en la que podría pensar es eliminar la cookie JSESSIONID en la acción de cierre de sesión. La forma de eliminar la cookie es establecer su edad en cero de la siguiente manera.

Cookie cookie = new Cookie(); cookie.setValue(null); cookie.setMaxAge(0); cookie.setPath("/");

Aquí he añadido el camino como root. Por favor verifique la cookie JSESSIONID en su navegador para la ruta correcta.

Una vez que tengas esto, agrega esto a la respuesta

response.addCookie(cookie);

Puedes poner este código en tu método exitPrime() .