RequestMatcherDelegatingWebInvocationPrivilegeEvaluator doesn't provided access to the ServletContext

Closes gh-10779
This commit is contained in:
Marcus Da Coregio 2022-01-31 09:24:59 -03:00
parent b1a905befe
commit 1c10c10f73
2 changed files with 35 additions and 4 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Collections;
import java.util.List; import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.RequestMatcherEntry; import org.springframework.security.web.util.matcher.RequestMatcherEntry;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;
/** /**
* A {@link WebInvocationPrivilegeEvaluator} which delegates to a list of * A {@link WebInvocationPrivilegeEvaluator} which delegates to a list of
@ -34,10 +36,13 @@ import org.springframework.util.Assert;
* @author Marcus Da Coregio * @author Marcus Da Coregio
* @since 5.5.5 * @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 final List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> delegates;
private ServletContext servletContext;
public RequestMatcherDelegatingWebInvocationPrivilegeEvaluator( public RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries) { List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries) {
Assert.notNull(requestMatcherPrivilegeEvaluatorsEntries, "requestMatcherPrivilegeEvaluators cannot be null"); 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) { 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) { for (RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> delegate : this.delegates) {
if (delegate.getRequestMatcher().matches(filterInvocation.getHttpRequest())) { if (delegate.getRequestMatcher().matches(filterInvocation.getHttpRequest())) {
return delegate.getEntry(); return delegate.getEntry();
@ -119,4 +124,9 @@ public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator imple
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Collections;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; 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.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher;
@ -158,6 +162,23 @@ class RequestMatcherDelegatingWebInvocationPrivilegeEvaluatorTests {
verifyNoMoreInteractions(spyDeny); 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 @Test
void constructorWhenPrivilegeEvaluatorsNullThenException() { void constructorWhenPrivilegeEvaluatorsNullThenException() {
RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> entry = new RequestMatcherEntry<>(this.alwaysMatch, RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> entry = new RequestMatcherEntry<>(this.alwaysMatch,