Explorar o código

RequestMatcherDelegatingWebInvocationPrivilegeEvaluator doesn't provided access to the ServletContext

Closes gh-10779
Marcus Da Coregio %!s(int64=3) %!d(string=hai) anos
pai
achega
a041e7c943

+ 13 - 3
web/src/main/java/org/springframework/security/web/access/RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,12 +19,14 @@ package org.springframework.security.web.access;
 import java.util.Collections;
 import java.util.List;
 
+import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 
 import org.springframework.security.core.Authentication;
 import org.springframework.security.web.FilterInvocation;
 import org.springframework.security.web.util.matcher.RequestMatcherEntry;
 import org.springframework.util.Assert;
+import org.springframework.web.context.ServletContextAware;
 
 /**
  * A {@link WebInvocationPrivilegeEvaluator} which delegates to a list of
@@ -34,10 +36,13 @@ import org.springframework.util.Assert;
  * @author Marcus Da Coregio
  * @since 5.5.5
  */
-public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator implements WebInvocationPrivilegeEvaluator {
+public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator
+		implements WebInvocationPrivilegeEvaluator, ServletContextAware {
 
 	private final List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> delegates;
 
+	private ServletContext servletContext;
+
 	public RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
 			List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries) {
 		Assert.notNull(requestMatcherPrivilegeEvaluatorsEntries, "requestMatcherPrivilegeEvaluators cannot be null");
@@ -110,7 +115,7 @@ public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator imple
 	}
 
 	private List<WebInvocationPrivilegeEvaluator> getDelegate(String contextPath, String uri, String method) {
-		FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method);
+		FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
 		for (RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> delegate : this.delegates) {
 			if (delegate.getRequestMatcher().matches(filterInvocation.getHttpRequest())) {
 				return delegate.getEntry();
@@ -119,4 +124,9 @@ public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator imple
 		return Collections.emptyList();
 	}
 
+	@Override
+	public void setServletContext(ServletContext servletContext) {
+		this.servletContext = servletContext;
+	}
+
 }

+ 22 - 1
web/src/test/java/org/springframework/security/web/access/RequestMatcherDelegatingWebInvocationPrivilegeEvaluatorTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,9 +20,13 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
 
+import org.springframework.mock.web.MockServletContext;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -158,6 +162,23 @@ class RequestMatcherDelegatingWebInvocationPrivilegeEvaluatorTests {
 		verifyNoMoreInteractions(spyDeny);
 	}
 
+	@Test
+	void isAllowedWhenServletContextIsSetThenPassedFilterInvocationHttpServletRequestHasServletContext() {
+		Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
+		MockServletContext servletContext = new MockServletContext();
+		ArgumentCaptor<HttpServletRequest> argumentCaptor = ArgumentCaptor.forClass(HttpServletRequest.class);
+		RequestMatcher requestMatcher = mock(RequestMatcher.class);
+		WebInvocationPrivilegeEvaluator wipe = mock(WebInvocationPrivilegeEvaluator.class);
+		RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> delegate = new RequestMatcherEntry<>(requestMatcher,
+				Collections.singletonList(wipe));
+		RequestMatcherDelegatingWebInvocationPrivilegeEvaluator requestMatcherWipe = new RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
+				Collections.singletonList(delegate));
+		requestMatcherWipe.setServletContext(servletContext);
+		requestMatcherWipe.isAllowed("/foo/index.jsp", token);
+		verify(requestMatcher).matches(argumentCaptor.capture());
+		assertThat(argumentCaptor.getValue().getServletContext()).isNotNull();
+	}
+
 	@Test
 	void constructorWhenPrivilegeEvaluatorsNullThenException() {
 		RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> entry = new RequestMatcherEntry<>(this.alwaysMatch,