@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2022 the original author or authors .
* Copyright 2002 - 2023 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 .
@ -22,6 +22,7 @@ import java.util.List;
@@ -22,6 +22,7 @@ import java.util.List;
import javax.servlet.DispatcherType ;
import javax.servlet.Servlet ;
import javax.servlet.http.HttpServletMapping ;
import org.junit.jupiter.api.BeforeEach ;
import org.junit.jupiter.api.Test ;
@ -29,8 +30,11 @@ import org.junit.jupiter.api.Test;
@@ -29,8 +30,11 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.context.ApplicationContext ;
import org.springframework.http.HttpMethod ;
import org.springframework.mock.web.MockHttpServletRequest ;
import org.springframework.security.config.MockServletContext ;
import org.springframework.security.config.TestMockHttpServletMappings ;
import org.springframework.security.config.annotation.ObjectPostProcessor ;
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.DispatcherServletDelegatingRequestMatcher ;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher ;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher ;
import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher ;
@ -43,6 +47,9 @@ import static org.assertj.core.api.Assertions.assertThat;
@@ -43,6 +47,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType ;
import static org.mockito.BDDMockito.given ;
import static org.mockito.Mockito.mock ;
import static org.mockito.Mockito.verify ;
import static org.mockito.Mockito.verifyNoInteractions ;
import static org.mockito.Mockito.verifyNoMoreInteractions ;
/ * *
* Tests for { @link AbstractRequestMatcherRegistry } .
@ -197,6 +204,8 @@ public class AbstractRequestMatcherRegistryTests {
@@ -197,6 +204,8 @@ public class AbstractRequestMatcherRegistryTests {
public void requestMatchersWhenNoDispatcherServletThenAntPathRequestMatcherType ( ) {
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "servletOne" , Servlet . class ) . addMapping ( "/one" ) ;
servletContext . addServlet ( "servletTwo" , Servlet . class ) . addMapping ( "/two" ) ;
List < RequestMatcher > requestMatchers = this . matcherRegistry . requestMatchers ( "/**" ) ;
assertThat ( requestMatchers ) . isNotEmpty ( ) ;
assertThat ( requestMatchers ) . hasSize ( 1 ) ;
@ -214,7 +223,26 @@ public class AbstractRequestMatcherRegistryTests {
@@ -214,7 +223,26 @@ public class AbstractRequestMatcherRegistryTests {
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "dispatcherServlet" , DispatcherServlet . class ) . addMapping ( "/" ) ;
servletContext . addServlet ( "servletTwo" , Servlet . class ) . addMapping ( "/servlet/**" ) ;
servletContext . addServlet ( "servletTwo" , DispatcherServlet . class ) . addMapping ( "/servlet/*" ) ;
assertThatExceptionOfType ( IllegalArgumentException . class )
. isThrownBy ( ( ) - > this . matcherRegistry . requestMatchers ( "/**" ) ) ;
}
@Test
public void requestMatchersWhenMultipleDispatcherServletMappingsThenException ( ) {
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "dispatcherServlet" , DispatcherServlet . class ) . addMapping ( "/" , "/mvc/*" ) ;
assertThatExceptionOfType ( IllegalArgumentException . class )
. isThrownBy ( ( ) - > this . matcherRegistry . requestMatchers ( "/**" ) ) ;
}
@Test
public void requestMatchersWhenPathDispatcherServletAndOtherServletsThenException ( ) {
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "dispatcherServlet" , DispatcherServlet . class ) . addMapping ( "/mvc/*" ) ;
servletContext . addServlet ( "default" , Servlet . class ) . addMapping ( "/" ) ;
assertThatExceptionOfType ( IllegalArgumentException . class )
. isThrownBy ( ( ) - > this . matcherRegistry . requestMatchers ( "/**" ) ) ;
}
@ -231,6 +259,87 @@ public class AbstractRequestMatcherRegistryTests {
@@ -231,6 +259,87 @@ public class AbstractRequestMatcherRegistryTests {
assertThat ( requestMatchers . get ( 0 ) ) . isInstanceOf ( MvcRequestMatcher . class ) ;
}
@Test
public void requestMatchersWhenOnlyDispatcherServletThenAllows ( ) {
mockMvcIntrospector ( true ) ;
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "dispatcherServlet" , DispatcherServlet . class ) . addMapping ( "/mvc/*" ) ;
List < RequestMatcher > requestMatchers = this . matcherRegistry . requestMatchers ( "/**" ) ;
assertThat ( requestMatchers ) . hasSize ( 1 ) ;
assertThat ( requestMatchers . get ( 0 ) ) . isInstanceOf ( MvcRequestMatcher . class ) ;
}
@Test
public void requestMatchersWhenImplicitServletsThenAllows ( ) {
mockMvcIntrospector ( true ) ;
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "defaultServlet" , Servlet . class ) ;
servletContext . addServlet ( "jspServlet" , Servlet . class ) . addMapping ( "*.jsp" , "*.jspx" ) ;
servletContext . addServlet ( "dispatcherServlet" , DispatcherServlet . class ) . addMapping ( "/" ) ;
List < RequestMatcher > requestMatchers = this . matcherRegistry . requestMatchers ( "/**" ) ;
assertThat ( requestMatchers ) . hasSize ( 1 ) ;
assertThat ( requestMatchers . get ( 0 ) ) . isInstanceOf ( DispatcherServletDelegatingRequestMatcher . class ) ;
}
@Test
public void requestMatchersWhenPathBasedNonDispatcherServletThenAllows ( ) {
mockMvcIntrospector ( true ) ;
MockServletContext servletContext = new MockServletContext ( ) ;
given ( this . context . getServletContext ( ) ) . willReturn ( servletContext ) ;
servletContext . addServlet ( "path" , Servlet . class ) . addMapping ( "/services/*" ) ;
servletContext . addServlet ( "default" , DispatcherServlet . class ) . addMapping ( "/" ) ;
List < RequestMatcher > requestMatchers = this . matcherRegistry . requestMatchers ( "/services/*" ) ;
assertThat ( requestMatchers ) . hasSize ( 1 ) ;
assertThat ( requestMatchers . get ( 0 ) ) . isInstanceOf ( DispatcherServletDelegatingRequestMatcher . class ) ;
MockHttpServletRequest request = new MockHttpServletRequest ( "GET" , "/services/endpoint" ) {
@Override
public HttpServletMapping getHttpServletMapping ( ) {
return TestMockHttpServletMappings . defaultMapping ( ) ;
}
} ;
assertThat ( requestMatchers . get ( 0 ) . matcher ( request ) . isMatch ( ) ) . isTrue ( ) ;
request = new MockHttpServletRequest ( "GET" , "/services/endpoint" ) {
@Override
public HttpServletMapping getHttpServletMapping ( ) {
return TestMockHttpServletMappings . path ( this , "/services" ) ;
}
} ;
request . setServletPath ( "/services" ) ;
request . setPathInfo ( "/endpoint" ) ;
assertThat ( requestMatchers . get ( 0 ) . matcher ( request ) . isMatch ( ) ) . isTrue ( ) ;
}
@Test
public void matchesWhenDispatcherServletThenMvc ( ) {
MockServletContext servletContext = new MockServletContext ( ) ;
servletContext . addServlet ( "default" , DispatcherServlet . class ) . addMapping ( "/" ) ;
servletContext . addServlet ( "path" , Servlet . class ) . addMapping ( "/services/*" ) ;
MvcRequestMatcher mvc = mock ( MvcRequestMatcher . class ) ;
AntPathRequestMatcher ant = mock ( AntPathRequestMatcher . class ) ;
DispatcherServletDelegatingRequestMatcher requestMatcher = new DispatcherServletDelegatingRequestMatcher ( ant ,
mvc , servletContext ) ;
MockHttpServletRequest request = new MockHttpServletRequest ( "GET" , "/services/endpoint" ) {
@Override
public HttpServletMapping getHttpServletMapping ( ) {
return TestMockHttpServletMappings . defaultMapping ( ) ;
}
} ;
assertThat ( requestMatcher . matches ( request ) ) . isFalse ( ) ;
verify ( mvc ) . matches ( request ) ;
verifyNoInteractions ( ant ) ;
request = new MockHttpServletRequest ( "GET" , "/services/endpoint" ) {
@Override
public HttpServletMapping getHttpServletMapping ( ) {
return TestMockHttpServletMappings . path ( this , "/services" ) ;
}
} ;
assertThat ( requestMatcher . matches ( request ) ) . isFalse ( ) ;
verify ( ant ) . matches ( request ) ;
verifyNoMoreInteractions ( mvc ) ;
}
private void mockMvcIntrospector ( boolean isPresent ) {
ApplicationContext context = this . matcherRegistry . getApplicationContext ( ) ;
given ( context . containsBean ( "mvcHandlerMappingIntrospector" ) ) . willReturn ( isPresent ) ;