diff --git a/spring-security-mvc-session/src/main/java/com/baeldung/web/SessionRestController.java b/spring-security-mvc-session/src/main/java/com/baeldung/web/SessionRestController.java new file mode 100644 index 0000000000..1353ee25d0 --- /dev/null +++ b/spring-security-mvc-session/src/main/java/com/baeldung/web/SessionRestController.java @@ -0,0 +1,17 @@ +package com.baeldung.web; + +import javax.servlet.http.HttpSession; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SessionRestController { + + @GetMapping("/session-max-interval") + @ResponseBody + public String retrieveMaxSessionIncativeInterval(HttpSession session) { + return "Max Inactive Interval before Session expires: " + session.getMaxInactiveInterval(); + } +} diff --git a/spring-security-mvc-session/src/main/resources/application.properties b/spring-security-mvc-session/src/main/resources/application.properties index 39ec0a0b27..56b2b7b123 100644 --- a/spring-security-mvc-session/src/main/resources/application.properties +++ b/spring-security-mvc-session/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.servlet.session.timeout=60s +server.servlet.session.timeout=65s spring.mvc.view.prefix=/WEB-INF/view/ spring.mvc.view.suffix=.jsp diff --git a/spring-security-mvc-session/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java b/spring-security-mvc-session/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java new file mode 100644 index 0000000000..5a9bf72077 --- /dev/null +++ b/spring-security-mvc-session/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java @@ -0,0 +1,92 @@ +package com.baeldung.session; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.filter.session.SessionFilter; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; + +/** + * This Live Test requires the service to be up and running. + */ +public class SessionConfigurationIntegrationTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SESSION_SVC_URL = "http://localhost:8080/session-max-interval"; + + @Test + public void givenValidUser_whenRequestResourceAfterSessionExpiration_thenRedirectedToInvalidSessionUri() throws Exception { + SessionFilter sessionFilter = new SessionFilter(); + simpleSvcRequestLoggingIn(sessionFilter); + Response resp2 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter); + assertThat(resp2.getStatusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(resp2.getBody() + .asString()).isEqualTo("Max Inactive Interval before Session expires: 60"); + + // session will be expired in 60 seconds... + Thread.sleep(62000); + Response resp3 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter); + + assertThat(resp3.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); + assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession.html"); + } + + @Test + public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() throws Exception { + SessionFilter sessionFilter = new SessionFilter(); + simpleSvcRequestLoggingIn(sessionFilter); + simpleSvcRequestLoggingIn(); + + // this login will expire the first session + simpleSvcRequestLoggingIn(); + + // now try to access a resource using expired session + Response resp4 = given().filter(sessionFilter) + .and() + .redirects() + .follow(false) + .when() + .get(SESSION_SVC_URL); + + assertThat(resp4.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); + assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired.html"); + } + + private static void simpleSvcRequestLoggingIn() { + simpleSvcRequestLoggingIn(null); + } + + private static void simpleSvcRequestLoggingIn(SessionFilter sessionFilter) { + Response response = simpleResponseSvcRequestLoggingIn(Optional.ofNullable(sessionFilter)); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.getBody() + .asString()).isEqualTo("Max Inactive Interval before Session expires: 60"); + } + + private static Response simpleResponseSvcRequestLoggingIn(Optional sessionFilter) { + RequestSpecification spec = given().auth() + .form(USER, PASSWORD); + sessionFilter.ifPresent(filter -> spec.and() + .filter(filter)); + return spec.when() + .get(SESSION_SVC_URL); + } + + private static Response simpleResponseRequestUsingSessionNotFollowingRedirects(SessionFilter sessionFilter) { + return given().filter(sessionFilter) + .and() + .redirects() + .follow(false) + .when() + .get(SESSION_SVC_URL); + } + +}