Request Cache supports matchingRequestParameterName

This commit is contained in:
Rob Winch
2022-06-29 18:19:11 -05:00
parent 38cb6c3172
commit 28c0d1459c
8 changed files with 294 additions and 22 deletions

View File

@@ -56,22 +56,42 @@ public class DefaultSavedRequestMixinTests extends AbstractMixinTests {
// @formatter:on
// @formatter:off
private static final String REQUEST_JSON = "{" +
"\"@class\": \"org.springframework.security.web.savedrequest.DefaultSavedRequest\", "
+ "\"cookies\": " + COOKIES_JSON + ","
+ "\"locales\": [\"java.util.ArrayList\", [\"en\"]], "
+ "\"headers\": {\"@class\": \"java.util.TreeMap\", \"x-auth-token\": [\"java.util.ArrayList\", [\"12\"]]}, "
+ "\"parameters\": {\"@class\": \"java.util.TreeMap\"},"
+ "\"contextPath\": \"\", "
+ "\"method\": \"\", "
+ "\"pathInfo\": null, "
+ "\"queryString\": null, "
+ "\"requestURI\": \"\", "
+ "\"requestURL\": \"http://localhost\", "
+ "\"scheme\": \"http\", "
+ "\"serverName\": \"localhost\", "
+ "\"servletPath\": \"\", "
+ "\"serverPort\": 80"
+ "}";
"\"@class\": \"org.springframework.security.web.savedrequest.DefaultSavedRequest\", "
+ "\"cookies\": " + COOKIES_JSON + ","
+ "\"locales\": [\"java.util.ArrayList\", [\"en\"]], "
+ "\"headers\": {\"@class\": \"java.util.TreeMap\", \"x-auth-token\": [\"java.util.ArrayList\", [\"12\"]]}, "
+ "\"parameters\": {\"@class\": \"java.util.TreeMap\"},"
+ "\"contextPath\": \"\", "
+ "\"method\": \"\", "
+ "\"pathInfo\": null, "
+ "\"queryString\": null, "
+ "\"requestURI\": \"\", "
+ "\"requestURL\": \"http://localhost\", "
+ "\"scheme\": \"http\", "
+ "\"serverName\": \"localhost\", "
+ "\"servletPath\": \"\", "
+ "\"serverPort\": 80"
+ "}";
// @formatter:on
// @formatter:off
private static final String REQUEST_WITH_MATCHING_REQUEST_PARAM_NAME_JSON = "{" +
"\"@class\": \"org.springframework.security.web.savedrequest.DefaultSavedRequest\", "
+ "\"cookies\": " + COOKIES_JSON + ","
+ "\"locales\": [\"java.util.ArrayList\", [\"en\"]], "
+ "\"headers\": {\"@class\": \"java.util.TreeMap\", \"x-auth-token\": [\"java.util.ArrayList\", [\"12\"]]}, "
+ "\"parameters\": {\"@class\": \"java.util.TreeMap\"},"
+ "\"contextPath\": \"\", "
+ "\"method\": \"\", "
+ "\"pathInfo\": null, "
+ "\"queryString\": null, "
+ "\"requestURI\": \"\", "
+ "\"requestURL\": \"http://localhost\", "
+ "\"scheme\": \"http\", "
+ "\"serverName\": \"localhost\", "
+ "\"servletPath\": \"\", "
+ "\"serverPort\": 80, "
+ "\"matchingRequestParameterName\": \"success\""
+ "}";
// @formatter:on
@Test
public void matchRequestBuildWithConstructorAndBuilder() {
@@ -126,4 +146,17 @@ public class DefaultSavedRequestMixinTests extends AbstractMixinTests {
assertThat(request.getHeaderValues("x-auth-token")).hasSize(1).contains("12");
}
@Test
public void deserializeWhenMatchingRequestParameterNameThenRedirectUrlContainsParam() throws IOException {
DefaultSavedRequest request = (DefaultSavedRequest) this.mapper
.readValue(REQUEST_WITH_MATCHING_REQUEST_PARAM_NAME_JSON, Object.class);
assertThat(request.getRedirectUrl()).isEqualTo("http://localhost?success");
}
@Test
public void deserializeWhenNullMatchingRequestParameterNameThenRedirectUrlDoesNotContainParam() throws IOException {
DefaultSavedRequest request = (DefaultSavedRequest) this.mapper.readValue(REQUEST_JSON, Object.class);
assertThat(request.getRedirectUrl()).isEqualTo("http://localhost");
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.security.web.savedrequest;
import java.net.URL;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -57,4 +59,67 @@ public class DefaultSavedRequestTests {
assertThat(saved.getParameterValues("anothertest")).isNull();
}
@Test
public void getRedirectUrlWhenNoQueryAndDefaultMatchingRequestParameterNameThenNoQuery() throws Exception {
DefaultSavedRequest savedRequest = new DefaultSavedRequest(new MockHttpServletRequest(),
new MockPortResolver(8080, 8443));
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasNoQuery();
}
@Test
public void getRedirectUrlWhenQueryAndDefaultMatchingRequestParameterNameNullThenNoQuery() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("foo=bar");
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443), null);
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasQuery("foo=bar");
}
@Test
public void getRedirectUrlWhenNoQueryAndNullMatchingRequestParameterNameThenNoQuery() throws Exception {
DefaultSavedRequest savedRequest = new DefaultSavedRequest(new MockHttpServletRequest(),
new MockPortResolver(8080, 8443), null);
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasNoQuery();
}
@Test
public void getRedirectUrlWhenNoQueryAndMatchingRequestParameterNameThenQuery() throws Exception {
DefaultSavedRequest savedRequest = new DefaultSavedRequest(new MockHttpServletRequest(),
new MockPortResolver(8080, 8443), "success");
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasQuery("success");
}
@Test
public void getRedirectUrlWhenQueryEmptyAndMatchingRequestParameterNameThenQuery() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("");
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443),
"success");
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasQuery("success");
}
@Test
public void getRedirectUrlWhenQueryEndsAmpersandAndMatchingRequestParameterNameThenQuery() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("foo=bar&");
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443),
"success");
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasQuery("foo=bar&success");
}
@Test
public void getRedirectUrlWhenQueryDoesNotEndAmpersandAndMatchingRequestParameterNameThenQuery() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("foo=bar");
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443),
"success");
assertThat(savedRequest.getParameterMap()).doesNotContainKey("success");
assertThat(new URL(savedRequest.getRedirectUrl())).hasQuery("foo=bar&success");
}
}

View File

@@ -32,6 +32,10 @@ import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.PortResolverImpl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* @author Luke Taylor
@@ -93,6 +97,30 @@ public class HttpSessionRequestCacheTests {
assertThat(request.getSession().getAttribute("CUSTOM_SAVED_REQUEST")).isNotNull();
}
@Test
public void getMatchingRequestWhenMatchingRequestParameterNameSetThenSessionNotAccessed() {
HttpSessionRequestCache cache = new HttpSessionRequestCache();
cache.setMatchingRequestParameterName("success");
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletRequest matchingRequest = cache.getMatchingRequest(request, new MockHttpServletResponse());
assertThat(matchingRequest).isNull();
verify(request, never()).getSession();
verify(request, never()).getSession(anyBoolean());
}
@Test
public void getMatchingRequestWhenMatchingRequestParameterNameSetAndParameterExistThenLookedUp() {
MockHttpServletRequest request = new MockHttpServletRequest();
HttpSessionRequestCache cache = new HttpSessionRequestCache();
cache.setMatchingRequestParameterName("success");
cache.saveRequest(request, new MockHttpServletResponse());
MockHttpServletRequest requestToMatch = new MockHttpServletRequest();
requestToMatch.setParameter("success", "");
requestToMatch.setSession(request.getSession());
HttpServletRequest matchingRequest = cache.getMatchingRequest(requestToMatch, new MockHttpServletResponse());
assertThat(matchingRequest).isNotNull();
}
private static final class CustomSavedRequest implements SavedRequest {
private final SavedRequest delegate;

View File

@@ -25,8 +25,13 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* @author Rob Winch
@@ -96,4 +101,27 @@ public class WebSessionServerRequestCacheTests {
assertThat(this.cache.getRedirectUri(exchange).block()).isNull();
}
@Test
public void removeMatchingRequestWhenNoParameter() {
this.cache.setMatchingRequestParameterName("success");
MockServerHttpRequest request = MockServerHttpRequest.get("/secured/").build();
ServerWebExchange exchange = mock(ServerWebExchange.class);
given(exchange.getRequest()).willReturn(request);
assertThat(this.cache.removeMatchingRequest(exchange).block()).isNull();
verify(exchange, never()).getSession();
}
@Test
public void removeMatchingRequestWhenParameter() {
this.cache.setMatchingRequestParameterName("success");
MockServerHttpRequest request = MockServerHttpRequest.get("/secured/").accept(MediaType.TEXT_HTML).build();
ServerWebExchange exchange = MockServerWebExchange.from(request);
this.cache.saveRequest(exchange).block();
String redirectUri = "/secured/?success";
assertThat(this.cache.getRedirectUri(exchange).block()).isEqualTo(URI.create(redirectUri));
MockServerHttpRequest redirectRequest = MockServerHttpRequest.get(redirectUri).build();
ServerWebExchange redirectExchange = exchange.mutate().request(redirectRequest).build();
assertThat(this.cache.removeMatchingRequest(redirectExchange).block()).isNotNull();
}
}