diff --git a/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java b/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java index 25729f7f..c35dc16f 100644 --- a/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java +++ b/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java @@ -105,7 +105,7 @@ public class RestMockMvcTests { @Bean public HttpSessionIdResolver httpSessionIdResolver() { - return new HeaderHttpSessionIdResolver(); + return HeaderHttpSessionIdResolver.xAuthToken(); } } diff --git a/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java b/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java index 6e621564..7b8a34ff 100644 --- a/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java +++ b/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java @@ -37,7 +37,7 @@ public class HttpSessionConfig { @Bean public HttpSessionIdResolver httpSessionIdResolver() { - return new HeaderHttpSessionIdResolver(); // <3> + return HeaderHttpSessionIdResolver.xAuthToken(); // <3> } } // end::class[] diff --git a/spring-session-core/src/main/java/org/springframework/session/web/http/HeaderHttpSessionIdResolver.java b/spring-session-core/src/main/java/org/springframework/session/web/http/HeaderHttpSessionIdResolver.java index 3a4dc3a4..9f8d8081 100644 --- a/spring-session-core/src/main/java/org/springframework/session/web/http/HeaderHttpSessionIdResolver.java +++ b/spring-session-core/src/main/java/org/springframework/session/web/http/HeaderHttpSessionIdResolver.java @@ -23,11 +23,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** - * A {@link HttpSessionIdResolver} that uses a header to obtain the session from. + * A {@link HttpSessionIdResolver} that uses a header to resolve the session id. * Specifically, this implementation will allow specifying a header name using - * {@link HeaderHttpSessionIdResolver#setHeaderName(String)}. The default is - * "X-Auth-Token". - * + * {@link #HeaderHttpSessionIdResolver(String)}. Convenience factory methods for creating + * instances that use common header names, such as "X-Auth-Token" and + * "Authentication-Info", are available as well. + *

* When a session is created, the HTTP response will have a response header of the * specified name and the value of the session id. For example: * @@ -59,7 +60,40 @@ import javax.servlet.http.HttpServletResponse; */ public class HeaderHttpSessionIdResolver implements HttpSessionIdResolver { - private String headerName = "X-Auth-Token"; + private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token"; + + private static final String HEADER_AUTHENTICATION_INFO = "Authentication-Info"; + + private final String headerName; + + /** + * Convenience factory to create {@link HeaderHttpSessionIdResolver} that uses + * "X-Auth-Token" header. + * @return the instance configured to use "X-Auth-Token" header + */ + public static HeaderHttpSessionIdResolver xAuthToken() { + return new HeaderHttpSessionIdResolver(HEADER_X_AUTH_TOKEN); + } + + /** + * Convenience factory to create {@link HeaderHttpSessionIdResolver} that uses + * "Authentication-Info" header. + * @return the instance configured to use "Authentication-Info" header + */ + public static HeaderHttpSessionIdResolver authenticationInfo() { + return new HeaderHttpSessionIdResolver(HEADER_AUTHENTICATION_INFO); + } + + /** + * The name of the header to obtain the session id from. + * @param headerName the name of the header to obtain the session id from. + */ + public HeaderHttpSessionIdResolver(String headerName) { + if (headerName == null) { + throw new IllegalArgumentException("headerName cannot be null"); + } + this.headerName = headerName; + } @Override public List resolveSessionIds(HttpServletRequest request) { @@ -79,16 +113,4 @@ public class HeaderHttpSessionIdResolver implements HttpSessionIdResolver { response.setHeader(this.headerName, ""); } - /** - * The name of the header to obtain the session id from. Default is "X-Auth-Token". - * - * @param headerName the name of the header to obtain the session id from. - */ - public void setHeaderName(String headerName) { - if (headerName == null) { - throw new IllegalArgumentException("headerName cannot be null"); - } - this.headerName = headerName; - } - } diff --git a/spring-session-core/src/test/java/org/springframework/session/web/http/HeaderHttpSessionIdResolverTests.java b/spring-session-core/src/test/java/org/springframework/session/web/http/HeaderHttpSessionIdResolverTests.java index 5172694d..298be06f 100644 --- a/spring-session-core/src/test/java/org/springframework/session/web/http/HeaderHttpSessionIdResolverTests.java +++ b/spring-session-core/src/test/java/org/springframework/session/web/http/HeaderHttpSessionIdResolverTests.java @@ -17,14 +17,16 @@ package org.springframework.session.web.http; import java.util.Collections; +import java.util.UUID; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.session.MapSession; -import org.springframework.session.Session; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -33,108 +35,105 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class HeaderHttpSessionIdResolverTests { + private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + private MockHttpServletRequest request; + private MockHttpServletResponse response; - private HeaderHttpSessionIdResolver strategy; - private String headerName; - private Session session; + private HeaderHttpSessionIdResolver resolver; @Before public void setup() throws Exception { - this.headerName = "X-Auth-Token"; - this.session = new MapSession(); this.request = new MockHttpServletRequest(); this.response = new MockHttpServletResponse(); - this.strategy = new HeaderHttpSessionIdResolver(); + this.resolver = HeaderHttpSessionIdResolver.xAuthToken(); } @Test - public void getRequestedSessionIdNull() throws Exception { - assertThat(this.strategy.resolveSessionIds(this.request)).isEmpty(); + public void createResolverWithXAuthTokenHeader() { + HeaderHttpSessionIdResolver resolver = HeaderHttpSessionIdResolver.xAuthToken(); + assertThat(ReflectionTestUtils.getField(resolver, "headerName")) + .isEqualTo("X-Auth-Token"); } @Test - public void getRequestedSessionIdNotNull() throws Exception { - setSessionId(this.session.getId()); - assertThat(this.strategy.resolveSessionIds(this.request)) - .isEqualTo(Collections.singletonList(this.session.getId())); + public void createResolverWithAuthenticationInfoHeader() { + HeaderHttpSessionIdResolver resolver = HeaderHttpSessionIdResolver + .authenticationInfo(); + assertThat(ReflectionTestUtils.getField(resolver, "headerName")) + .isEqualTo("Authentication-Info"); } @Test - public void getRequestedSessionIdNotNullCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - setSessionId(this.session.getId()); - assertThat(this.strategy.resolveSessionIds(this.request)) - .isEqualTo(Collections.singletonList(this.session.getId())); + public void createResolverWithCustomHeaderName() { + HeaderHttpSessionIdResolver resolver = new HeaderHttpSessionIdResolver( + "Custom-Header"); + assertThat(ReflectionTestUtils.getField(resolver, "headerName")) + .isEqualTo("Custom-Header"); } @Test - public void onNewSession() throws Exception { - String sessionId = this.session.getId(); - this.strategy.setSessionId(this.request, this.response, sessionId); - assertThat(getSessionId()).isEqualTo(sessionId); - } - - // the header is set as apposed to added - @Test - public void onNewSessionMulti() throws Exception { - String sessionId = this.session.getId(); - this.strategy.setSessionId(this.request, this.response, sessionId); - this.strategy.setSessionId(this.request, this.response, sessionId); - - assertThat(this.response.getHeaders(this.headerName).size()).isEqualTo(1); - assertThat(this.response.getHeaders(this.headerName)) - .containsOnly(sessionId); + public void createResolverWithNullHeaderName() { + this.thrown.expect(IllegalArgumentException.class); + this.thrown.expectMessage("headerName cannot be null"); + new HeaderHttpSessionIdResolver(null); } @Test - public void onNewSessionCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - String sessionId = this.session.getId(); - this.strategy.setSessionId(this.request, this.response, sessionId); + public void getRequestedSessionIdNull() { + assertThat(this.resolver.resolveSessionIds(this.request)).isEmpty(); + } + + @Test + public void getRequestedSessionIdNotNull() { + String sessionId = UUID.randomUUID().toString(); + setSessionId(sessionId); + assertThat(this.resolver.resolveSessionIds(this.request)) + .isEqualTo(Collections.singletonList(sessionId)); + } + + @Test + public void onNewSession() { + String sessionId = UUID.randomUUID().toString(); + this.resolver.setSessionId(this.request, this.response, sessionId); assertThat(getSessionId()).isEqualTo(sessionId); } @Test - public void onDeleteSession() throws Exception { - this.strategy.expireSession(this.request, this.response); + public void onDeleteSession() { + this.resolver.expireSession(this.request, this.response); assertThat(getSessionId()).isEmpty(); } // the header is set as apposed to added @Test - public void onDeleteSessionMulti() throws Exception { - this.strategy.expireSession(this.request, this.response); - this.strategy.expireSession(this.request, this.response); - - assertThat(this.response.getHeaders(this.headerName).size()).isEqualTo(1); - assertThat(getSessionId()).isEmpty(); + public void onNewSessionMulti() { + String sessionId = UUID.randomUUID().toString(); + this.resolver.setSessionId(this.request, this.response, sessionId); + this.resolver.setSessionId(this.request, this.response, sessionId); + assertThat(this.response.getHeaders(HEADER_X_AUTH_TOKEN).size()).isEqualTo(1); + assertThat(this.response.getHeaders(HEADER_X_AUTH_TOKEN)).containsOnly(sessionId); } + // the header is set as apposed to added @Test - public void onDeleteSessionCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - this.strategy.expireSession(this.request, this.response); + public void onDeleteSessionMulti() { + this.resolver.expireSession(this.request, this.response); + this.resolver.expireSession(this.request, this.response); + assertThat(this.response.getHeaders(HEADER_X_AUTH_TOKEN).size()).isEqualTo(1); assertThat(getSessionId()).isEmpty(); } - @Test(expected = IllegalArgumentException.class) - public void setHeaderNameNull() throws Exception { - this.strategy.setHeaderName(null); - } - - private void setHeaderName(String headerName) { - this.strategy.setHeaderName(headerName); - this.headerName = headerName; - } - - private void setSessionId(String id) { - this.request.addHeader(this.headerName, id); + private void setSessionId(String sessionId) { + this.request.addHeader(HEADER_X_AUTH_TOKEN, sessionId); } private String getSessionId() { - return this.response.getHeader(this.headerName); + return this.response.getHeader(HEADER_X_AUTH_TOKEN); } }