Add HeaderHttpSessionIdResolver factory methods for commonly used headers

Closes gh-706
This commit is contained in:
Vedran Pavic
2017-10-30 07:39:19 +01:00
parent 34f29cf36c
commit 91d4a5bfca
4 changed files with 103 additions and 82 deletions

View File

@@ -105,7 +105,7 @@ public class RestMockMvcTests {
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return new HeaderHttpSessionIdResolver();
return HeaderHttpSessionIdResolver.xAuthToken();
}
}

View File

@@ -37,7 +37,7 @@ public class HttpSessionConfig {
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return new HeaderHttpSessionIdResolver(); // <3>
return HeaderHttpSessionIdResolver.xAuthToken(); // <3>
}
}
// end::class[]

View File

@@ -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.
* <p>
* 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<String> 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;
}
}

View File

@@ -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);
}
}