From fa4806dbcc6455b0bd76c2af24b5024f9cfc7ef4 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Tue, 2 Sep 2025 16:06:03 -0600 Subject: [PATCH] Move Web Access API Issue gh-17847 --- access/spring-security-access.gradle | 4 ++ ...efaultWebInvocationPrivilegeEvaluator.java | 0 .../channel/AbstractRetryEntryPoint.java | 0 .../channel/ChannelDecisionManager.java | 0 .../channel/ChannelDecisionManagerImpl.java | 0 .../web/access/channel/ChannelEntryPoint.java | 0 .../channel/ChannelProcessingFilter.java | 0 .../web/access/channel/ChannelProcessor.java | 0 .../channel/InsecureChannelProcessor.java | 0 .../channel/RetryWithHttpEntryPoint.java | 0 .../channel/RetryWithHttpsEntryPoint.java | 0 .../channel/SecureChannelProcessor.java | 0 .../web/access/channel/package-info.java | 0 .../DefaultWebSecurityExpressionHandler.java | 0 ...ilterInvocationSecurityMetadataSource.java | 0 .../WebExpressionConfigAttribute.java | 0 .../access/expression/WebExpressionVoter.java | 0 ...ilterInvocationSecurityMetadataSource.java | 0 ...ilterInvocationSecurityMetadataSource.java | 0 .../intercept/FilterSecurityInterceptor.java | 0 ...tWebInvocationPrivilegeEvaluatorTests.java | 48 +++++++++---------- .../ChannelDecisionManagerImplTests.java | 7 +-- .../channel/ChannelProcessingFilterTests.java | 8 ++-- .../InsecureChannelProcessorTests.java | 13 +++-- .../channel/RetryWithHttpEntryPointTests.java | 0 .../RetryWithHttpsEntryPointTests.java | 0 .../channel/SecureChannelProcessorTests.java | 13 +++-- ...aultWebSecurityExpressionHandlerTests.java | 0 ...InvocationSecurityMetadataSourceTests.java | 0 .../expression/WebExpressionVoterTests.java | 0 ...InvocationSecurityMetadataSourceTests.java | 14 +++--- .../FilterSecurityInterceptorTests.java | 4 +- taglibs/spring-security-taglibs.gradle | 1 + web/spring-security-web.gradle | 1 - ...ultHttpSecurityExpressionHandlerTests.java | 8 ++-- 35 files changed, 67 insertions(+), 54 deletions(-) rename {web => access}/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/channel/package-info.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java (100%) rename {web => access}/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java (72%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java (96%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java (95%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java (88%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java (88%) rename {web => access}/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java (100%) rename {web => access}/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java (90%) rename {web => access}/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java (97%) diff --git a/access/spring-security-access.gradle b/access/spring-security-access.gradle index 355bac90b2..cf176ec074 100644 --- a/access/spring-security-access.gradle +++ b/access/spring-security-access.gradle @@ -12,6 +12,7 @@ dependencies { api 'io.micrometer:micrometer-observation' optional project(':spring-security-messaging') + optional project(':spring-security-web') optional 'org.springframework:spring-websocket' optional 'com.fasterxml.jackson.core:jackson-databind' optional 'io.micrometer:context-propagation' @@ -22,6 +23,9 @@ dependencies { optional 'org.springframework:spring-tx' optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor' + provided 'jakarta.servlet:jakarta.servlet-api' + + testImplementation project(path : ':spring-security-web', configuration : 'tests') testImplementation 'commons-collections:commons-collections' testImplementation 'io.projectreactor:reactor-test' testImplementation "org.assertj:assertj-core" diff --git a/web/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java b/access/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java rename to access/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java rename to access/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java rename to access/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java rename to access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java rename to access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java rename to access/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java diff --git a/web/src/main/java/org/springframework/security/web/access/channel/package-info.java b/access/src/main/java/org/springframework/security/web/access/channel/package-info.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/channel/package-info.java rename to access/src/main/java/org/springframework/security/web/access/channel/package-info.java diff --git a/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java b/access/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java rename to access/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java diff --git a/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java rename to access/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java diff --git a/web/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java b/access/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java rename to access/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java diff --git a/web/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java b/access/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java rename to access/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java rename to access/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java rename to access/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java b/access/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java similarity index 100% rename from web/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java rename to access/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java diff --git a/web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java b/access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java similarity index 72% rename from web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java rename to access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java index 4216da2869..3dd7f12d8e 100644 --- a/web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java +++ b/access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java @@ -16,9 +16,13 @@ package org.springframework.security.web.access; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.BDDMockito; +import org.mockito.Mockito; import org.springframework.context.ApplicationEventPublisher; import org.springframework.mock.web.MockServletContext; @@ -33,15 +37,6 @@ import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - /** * Tests * {@link org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator}. @@ -61,43 +56,45 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests { @BeforeEach public final void setUp() { this.interceptor = new FilterSecurityInterceptor(); - this.ods = mock(FilterInvocationSecurityMetadataSource.class); - this.adm = mock(AccessDecisionManager.class); - this.ram = mock(RunAsManager.class); - this.interceptor.setAuthenticationManager(mock(AuthenticationManager.class)); + this.ods = Mockito.mock(FilterInvocationSecurityMetadataSource.class); + this.adm = Mockito.mock(AccessDecisionManager.class); + this.ram = Mockito.mock(RunAsManager.class); + this.interceptor.setAuthenticationManager(Mockito.mock(AuthenticationManager.class)); this.interceptor.setSecurityMetadataSource(this.ods); this.interceptor.setAccessDecisionManager(this.adm); this.interceptor.setRunAsManager(this.ram); - this.interceptor.setApplicationEventPublisher(mock(ApplicationEventPublisher.class)); + this.interceptor.setApplicationEventPublisher(Mockito.mock(ApplicationEventPublisher.class)); SecurityContextHolder.clearContext(); } @Test public void permitsAccessIfNoMatchingAttributesAndPublicInvocationsAllowed() { DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); - given(this.ods.getAttributes(any())).willReturn(null); - assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isTrue(); + BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null); + Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class))) + .isTrue(); } @Test public void deniesAccessIfNoMatchingAttributesAndPublicInvocationsNotAllowed() { DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); - given(this.ods.getAttributes(any())).willReturn(null); + BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null); this.interceptor.setRejectPublicInvocations(true); - assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isFalse(); + Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class))) + .isFalse(); } @Test public void deniesAccessIfAuthenticationIsNull() { DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); - assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse(); + Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse(); } @Test public void allowsAccessIfAccessDecisionManagerDoes() { Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX"); DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); - assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue(); + Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue(); } @SuppressWarnings("unchecked") @@ -105,8 +102,10 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests { public void deniesAccessIfAccessDecisionManagerDoes() { Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX"); DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); - willThrow(new AccessDeniedException("")).given(this.adm).decide(any(Authentication.class), any(), anyList()); - assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse(); + BDDMockito.willThrow(new AccessDeniedException("")) + .given(this.adm) + .decide(ArgumentMatchers.any(Authentication.class), ArgumentMatchers.any(), ArgumentMatchers.anyList()); + Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse(); } @Test @@ -118,8 +117,9 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests { DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor); wipe.setServletContext(servletContext); wipe.isAllowed("/foo/index.jsp", token); - verify(this.adm).decide(eq(token), filterInvocationArgumentCaptor.capture(), any()); - assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull(); + Mockito.verify(this.adm) + .decide(ArgumentMatchers.eq(token), filterInvocationArgumentCaptor.capture(), ArgumentMatchers.any()); + Assertions.assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull(); } } diff --git a/web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java b/access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java similarity index 96% rename from web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java index 4ab06ff409..e550801303 100644 --- a/web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java +++ b/access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Vector; import jakarta.servlet.FilterChain; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; @@ -85,7 +86,7 @@ public class ChannelDecisionManagerImplTests { FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class)); List cad = SecurityConfig.createList("xyz"); cdm.decide(fi, cad); - assertThat(fi.getResponse().isCommitted()).isTrue(); + Assertions.assertThat(fi.getResponse().isCommitted()).isTrue(); } @Test @@ -100,7 +101,7 @@ public class ChannelDecisionManagerImplTests { MockHttpServletResponse response = new MockHttpServletResponse(); FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class)); cdm.decide(fi, SecurityConfig.createList(new String[] { "abc", "ANY_CHANNEL" })); - assertThat(fi.getResponse().isCommitted()).isFalse(); + Assertions.assertThat(fi.getResponse().isCommitted()).isFalse(); } @Test @@ -117,7 +118,7 @@ public class ChannelDecisionManagerImplTests { MockHttpServletResponse response = new MockHttpServletResponse(); FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class)); cdm.decide(fi, SecurityConfig.createList("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT")); - assertThat(fi.getResponse().isCommitted()).isFalse(); + Assertions.assertThat(fi.getResponse().isCommitted()).isFalse(); } @Test diff --git a/web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java b/access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java similarity index 95% rename from web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java index ad3f3afa66..d486d36189 100644 --- a/web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java +++ b/access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java @@ -28,11 +28,11 @@ import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; +import org.springframework.security.web.servlet.TestMockHttpServletRequests; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.mock; -import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get; /** * Tests {@link ChannelProcessingFilter}. @@ -82,7 +82,7 @@ public class ChannelProcessingFilterTests { filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE")); MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE"); filter.setSecurityMetadataSource(fids); - MockHttpServletRequest request = get("/path").build(); + MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build(); request.setQueryString("info=now"); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, mock(FilterChain.class)); @@ -94,7 +94,7 @@ public class ChannelProcessingFilterTests { filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE")); MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE"); filter.setSecurityMetadataSource(fids); - MockHttpServletRequest request = get("/path").build(); + MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build(); request.setQueryString("info=now"); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, mock(FilterChain.class)); @@ -106,7 +106,7 @@ public class ChannelProcessingFilterTests { filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED")); MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED"); filter.setSecurityMetadataSource(fids); - MockHttpServletRequest request = get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build(); + MockHttpServletRequest request = TestMockHttpServletRequests.get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build(); request.setQueryString("info=now"); MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, mock(FilterChain.class)); diff --git a/web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java b/access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java similarity index 88% rename from web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java index 1c290cac06..6b4f1d8bae 100644 --- a/web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java +++ b/access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java @@ -17,17 +17,18 @@ package org.springframework.security.web.access.channel; import jakarta.servlet.FilterChain; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.servlet.TestMockHttpServletRequests; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.mock; -import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get; /** * Tests {@link InsecureChannelProcessor}. @@ -38,19 +39,21 @@ public class InsecureChannelProcessorTests { @Test public void testDecideDetectsAcceptableChannel() throws Exception { - MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null) + MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080") + .requestUri("/bigapp", "/servlet", null) .queryString("info=true") .build(); MockHttpServletResponse response = new MockHttpServletResponse(); FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class)); InsecureChannelProcessor processor = new InsecureChannelProcessor(); processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL")); - assertThat(fi.getResponse().isCommitted()).isFalse(); + Assertions.assertThat(fi.getResponse().isCommitted()).isFalse(); } @Test public void testDecideDetectsUnacceptableChannel() throws Exception { - MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null) + MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443") + .requestUri("/bigapp", "/servlet", null) .queryString("info=true") .build(); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -58,7 +61,7 @@ public class InsecureChannelProcessorTests { InsecureChannelProcessor processor = new InsecureChannelProcessor(); processor.decide(fi, SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL" })); - assertThat(fi.getResponse().isCommitted()).isTrue(); + Assertions.assertThat(fi.getResponse().isCommitted()).isTrue(); } @Test diff --git a/web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java b/access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java similarity index 100% rename from web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java diff --git a/web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java b/access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java similarity index 100% rename from web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java diff --git a/web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java b/access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java similarity index 88% rename from web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java rename to access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java index 4263cec233..f67d0ae7b3 100644 --- a/web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java +++ b/access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java @@ -17,17 +17,18 @@ package org.springframework.security.web.access.channel; import jakarta.servlet.FilterChain; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.servlet.TestMockHttpServletRequests; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.mock; -import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get; /** * Tests {@link SecureChannelProcessor}. @@ -38,19 +39,21 @@ public class SecureChannelProcessorTests { @Test public void testDecideDetectsAcceptableChannel() throws Exception { - MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null) + MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443") + .requestUri("/bigapp", "/servlet", null) .queryString("info=true") .build(); MockHttpServletResponse response = new MockHttpServletResponse(); FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class)); SecureChannelProcessor processor = new SecureChannelProcessor(); processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL")); - assertThat(fi.getResponse().isCommitted()).isFalse(); + Assertions.assertThat(fi.getResponse().isCommitted()).isFalse(); } @Test public void testDecideDetectsUnacceptableChannel() throws Exception { - MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null) + MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080") + .requestUri("/bigapp", "/servlet", null) .queryString("info=true") .build(); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -58,7 +61,7 @@ public class SecureChannelProcessorTests { SecureChannelProcessor processor = new SecureChannelProcessor(); processor.decide(fi, SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL" })); - assertThat(fi.getResponse().isCommitted()).isTrue(); + Assertions.assertThat(fi.getResponse().isCommitted()).isTrue(); } @Test diff --git a/web/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java b/access/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java similarity index 100% rename from web/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java rename to access/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java diff --git a/web/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java similarity index 100% rename from web/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java rename to access/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java diff --git a/web/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java b/access/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java similarity index 100% rename from web/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java rename to access/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java diff --git a/web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java similarity index 90% rename from web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java rename to access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java index dd746f35a6..3de762fd5e 100644 --- a/web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java +++ b/access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java @@ -28,12 +28,12 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.servlet.TestMockHttpServletRequests; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.springframework.security.web.servlet.TestMockHttpServletRequests.request; -import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; /** * Tests {@link DefaultFilterInvocationSecurityMetadataSource}. @@ -48,7 +48,7 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests { private void createFids(String pattern, HttpMethod method) { LinkedHashMap> requestMap = new LinkedHashMap<>(); - requestMap.put(pathPattern(method, pattern), this.def); + requestMap.put(PathPatternRequestMatcher.pathPattern(method, pattern), this.def); this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap); } @@ -117,8 +117,9 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests { public void mixingPatternsWithAndWithoutHttpMethodsIsSupported() { LinkedHashMap> requestMap = new LinkedHashMap<>(); Collection userAttrs = SecurityConfig.createList("A"); - requestMap.put(pathPattern("/user/**"), userAttrs); - requestMap.put(pathPattern(HttpMethod.GET, "/teller/**"), SecurityConfig.createList("B")); + requestMap.put(PathPatternRequestMatcher.pathPattern("/user/**"), userAttrs); + requestMap.put(PathPatternRequestMatcher.pathPattern(HttpMethod.GET, "/teller/**"), + SecurityConfig.createList("B")); this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap); FilterInvocation fi = createFilterInvocation("/user", null, null, "GET"); Collection attrs = this.fids.getAttributes(fi); @@ -141,7 +142,8 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests { private FilterInvocation createFilterInvocation(String servletPath, String pathInfo, String queryString, String method) { - MockHttpServletRequest request = request(method).requestUri(null, servletPath, pathInfo) + MockHttpServletRequest request = TestMockHttpServletRequests.request(method) + .requestUri(null, servletPath, pathInfo) .queryString(queryString) .build(); return new FilterInvocation(request, new MockHttpServletResponse(), mock(FilterChain.class)); diff --git a/web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java similarity index 97% rename from web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java rename to access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java index 77370b0cd7..5194c38325 100644 --- a/web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java +++ b/access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java @@ -39,6 +39,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.FilterInvocation; +import org.springframework.security.web.servlet.TestMockHttpServletRequests; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -53,7 +54,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get; /** * Tests {@link FilterSecurityInterceptor}. @@ -189,7 +189,7 @@ public class FilterSecurityInterceptorTests { private FilterInvocation createinvocation() { MockHttpServletResponse response = new MockHttpServletResponse(); - MockHttpServletRequest request = get("/secure/page.html").build(); + MockHttpServletRequest request = TestMockHttpServletRequests.get("/secure/page.html").build(); FilterChain chain = mock(FilterChain.class); FilterInvocation fi = new FilterInvocation(request, response, chain); return fi; diff --git a/taglibs/spring-security-taglibs.gradle b/taglibs/spring-security-taglibs.gradle index 7ef22c9819..875bf8220a 100644 --- a/taglibs/spring-security-taglibs.gradle +++ b/taglibs/spring-security-taglibs.gradle @@ -21,6 +21,7 @@ dependencies { testRuntimeOnly 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api' + testImplementation project(':spring-security-access') testImplementation "org.assertj:assertj-core" testImplementation "org.junit.jupiter:junit-jupiter-api" testImplementation "org.junit.jupiter:junit-jupiter-params" diff --git a/web/spring-security-web.gradle b/web/spring-security-web.gradle index d4113fed83..87ce691e0c 100644 --- a/web/spring-security-web.gradle +++ b/web/spring-security-web.gradle @@ -39,7 +39,6 @@ dependencies { api 'org.springframework:spring-expression' api 'org.springframework:spring-web' - optional project(':spring-security-access') optional 'com.fasterxml.jackson.core:jackson-databind' optional 'io.micrometer:context-propagation' optional 'io.projectreactor:reactor-core' diff --git a/web/src/test/java/org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandlerTests.java b/web/src/test/java/org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandlerTests.java index 9184d92217..8643754779 100644 --- a/web/src/test/java/org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandlerTests.java +++ b/web/src/test/java/org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandlerTests.java @@ -32,10 +32,10 @@ import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.TypedValue; -import org.springframework.security.access.SecurityConfig; import org.springframework.security.access.expression.SecurityExpressionRoot; import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; @@ -73,15 +73,15 @@ public class DefaultHttpSecurityExpressionHandlerTests { @Test public void expressionPropertiesAreResolvedAgainstAppContextBeans() { StaticApplicationContext appContext = new StaticApplicationContext(); - RootBeanDefinition bean = new RootBeanDefinition(SecurityConfig.class); + RootBeanDefinition bean = new RootBeanDefinition(SimpleGrantedAuthority.class); bean.getConstructorArgumentValues().addGenericArgumentValue("ROLE_A"); appContext.registerBeanDefinition("role", bean); this.handler.setApplicationContext(appContext); EvaluationContext ctx = this.handler.createEvaluationContext(mock(Authentication.class), mock(RequestAuthorizationContext.class)); ExpressionParser parser = this.handler.getExpressionParser(); - assertThat(parser.parseExpression("@role.getAttribute() == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue(); - assertThat(parser.parseExpression("@role.attribute == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue(); + assertThat(parser.parseExpression("@role.getAuthority() == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue(); + assertThat(parser.parseExpression("@role.authority == 'ROLE_A'").getValue(ctx, Boolean.class)).isTrue(); } @Test