1
1
/*
2
- * Copyright 2002-2022 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
26
26
import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
27
27
import org .springframework .context .ApplicationContext ;
28
28
import org .springframework .http .HttpMethod ;
29
+ import org .springframework .mock .web .MockHttpServletRequest ;
29
30
import org .springframework .security .config .MockServletContext ;
31
+ import org .springframework .security .config .TestMockHttpServletMappings ;
30
32
import org .springframework .security .config .annotation .ObjectPostProcessor ;
33
+ import org .springframework .security .config .annotation .web .AbstractRequestMatcherRegistry .DispatcherServletDelegatingRequestMatcher ;
31
34
import org .springframework .security .web .servlet .util .matcher .MvcRequestMatcher ;
32
35
import org .springframework .security .web .util .matcher .AntPathRequestMatcher ;
33
36
import org .springframework .security .web .util .matcher .DispatcherTypeRequestMatcher ;
40
43
import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
41
44
import static org .mockito .BDDMockito .given ;
42
45
import static org .mockito .Mockito .mock ;
46
+ import static org .mockito .Mockito .verify ;
47
+ import static org .mockito .Mockito .verifyNoInteractions ;
48
+ import static org .mockito .Mockito .verifyNoMoreInteractions ;
43
49
44
50
/**
45
51
* Tests for {@link AbstractRequestMatcherRegistry}.
@@ -159,6 +165,8 @@ public void requestMatchersWhenMvcPresentInClassPathAndMvcIntrospectorBeanNotAva
159
165
public void requestMatchersWhenNoDispatcherServletThenAntPathRequestMatcherType () {
160
166
MockServletContext servletContext = new MockServletContext ();
161
167
given (this .context .getServletContext ()).willReturn (servletContext );
168
+ servletContext .addServlet ("servletOne" , Servlet .class ).addMapping ("/one" );
169
+ servletContext .addServlet ("servletTwo" , Servlet .class ).addMapping ("/two" );
162
170
List <RequestMatcher > requestMatchers = this .matcherRegistry .requestMatchers ("/**" );
163
171
assertThat (requestMatchers ).isNotEmpty ();
164
172
assertThat (requestMatchers ).hasSize (1 );
@@ -170,7 +178,26 @@ public void requestMatchersWhenAmbiguousServletsThenException() {
170
178
MockServletContext servletContext = new MockServletContext ();
171
179
given (this .context .getServletContext ()).willReturn (servletContext );
172
180
servletContext .addServlet ("dispatcherServlet" , DispatcherServlet .class ).addMapping ("/" );
173
- servletContext .addServlet ("servletTwo" , Servlet .class ).addMapping ("/servlet/**" );
181
+ servletContext .addServlet ("servletTwo" , DispatcherServlet .class ).addMapping ("/servlet/*" );
182
+ assertThatExceptionOfType (IllegalArgumentException .class )
183
+ .isThrownBy (() -> this .matcherRegistry .requestMatchers ("/**" ));
184
+ }
185
+
186
+ @ Test
187
+ public void requestMatchersWhenMultipleDispatcherServletMappingsThenException () {
188
+ MockServletContext servletContext = new MockServletContext ();
189
+ given (this .context .getServletContext ()).willReturn (servletContext );
190
+ servletContext .addServlet ("dispatcherServlet" , DispatcherServlet .class ).addMapping ("/" , "/mvc/*" );
191
+ assertThatExceptionOfType (IllegalArgumentException .class )
192
+ .isThrownBy (() -> this .matcherRegistry .requestMatchers ("/**" ));
193
+ }
194
+
195
+ @ Test
196
+ public void requestMatchersWhenPathDispatcherServletAndOtherServletsThenException () {
197
+ MockServletContext servletContext = new MockServletContext ();
198
+ given (this .context .getServletContext ()).willReturn (servletContext );
199
+ servletContext .addServlet ("dispatcherServlet" , DispatcherServlet .class ).addMapping ("/mvc/*" );
200
+ servletContext .addServlet ("default" , Servlet .class ).addMapping ("/" );
174
201
assertThatExceptionOfType (IllegalArgumentException .class )
175
202
.isThrownBy (() -> this .matcherRegistry .requestMatchers ("/**" ));
176
203
}
@@ -187,6 +214,67 @@ public void requestMatchersWhenUnmappableServletsThenSkips() {
187
214
assertThat (requestMatchers .get (0 )).isInstanceOf (MvcRequestMatcher .class );
188
215
}
189
216
217
+ @ Test
218
+ public void requestMatchersWhenOnlyDispatcherServletThenAllows () {
219
+ MockServletContext servletContext = new MockServletContext ();
220
+ given (this .context .getServletContext ()).willReturn (servletContext );
221
+ servletContext .addServlet ("dispatcherServlet" , DispatcherServlet .class ).addMapping ("/mvc/*" );
222
+ List <RequestMatcher > requestMatchers = this .matcherRegistry .requestMatchers ("/**" );
223
+ assertThat (requestMatchers ).hasSize (1 );
224
+ assertThat (requestMatchers .get (0 )).isInstanceOf (MvcRequestMatcher .class );
225
+ }
226
+
227
+ @ Test
228
+ public void requestMatchersWhenImplicitServletsThenAllows () {
229
+ mockMvcIntrospector (true );
230
+ MockServletContext servletContext = new MockServletContext ();
231
+ given (this .context .getServletContext ()).willReturn (servletContext );
232
+ servletContext .addServlet ("defaultServlet" , Servlet .class );
233
+ servletContext .addServlet ("jspServlet" , Servlet .class ).addMapping ("*.jsp" , "*.jspx" );
234
+ servletContext .addServlet ("dispatcherServlet" , DispatcherServlet .class ).addMapping ("/" );
235
+ List <RequestMatcher > requestMatchers = this .matcherRegistry .requestMatchers ("/**" );
236
+ assertThat (requestMatchers ).hasSize (1 );
237
+ assertThat (requestMatchers .get (0 )).isInstanceOf (DispatcherServletDelegatingRequestMatcher .class );
238
+ }
239
+
240
+ @ Test
241
+ public void requestMatchersWhenPathBasedNonDispatcherServletThenAllows () {
242
+ MockServletContext servletContext = new MockServletContext ();
243
+ given (this .context .getServletContext ()).willReturn (servletContext );
244
+ servletContext .addServlet ("path" , Servlet .class ).addMapping ("/services/*" );
245
+ servletContext .addServlet ("default" , DispatcherServlet .class ).addMapping ("/" );
246
+ List <RequestMatcher > requestMatchers = this .matcherRegistry .requestMatchers ("/services/*" );
247
+ assertThat (requestMatchers ).hasSize (1 );
248
+ assertThat (requestMatchers .get (0 )).isInstanceOf (DispatcherServletDelegatingRequestMatcher .class );
249
+ MockHttpServletRequest request = new MockHttpServletRequest ("GET" , "/services/endpoint" );
250
+ request .setHttpServletMapping (TestMockHttpServletMappings .defaultMapping ());
251
+ assertThat (requestMatchers .get (0 ).matcher (request ).isMatch ()).isTrue ();
252
+ request .setHttpServletMapping (TestMockHttpServletMappings .path (request , "/services" ));
253
+ request .setServletPath ("/services" );
254
+ request .setPathInfo ("/endpoint" );
255
+ assertThat (requestMatchers .get (0 ).matcher (request ).isMatch ()).isTrue ();
256
+ }
257
+
258
+ @ Test
259
+ public void matchesWhenDispatcherServletThenMvc () {
260
+ MockServletContext servletContext = new MockServletContext ();
261
+ servletContext .addServlet ("default" , DispatcherServlet .class ).addMapping ("/" );
262
+ servletContext .addServlet ("path" , Servlet .class ).addMapping ("/services/*" );
263
+ MvcRequestMatcher mvc = mock (MvcRequestMatcher .class );
264
+ AntPathRequestMatcher ant = mock (AntPathRequestMatcher .class );
265
+ DispatcherServletDelegatingRequestMatcher requestMatcher = new DispatcherServletDelegatingRequestMatcher (ant ,
266
+ mvc , servletContext );
267
+ MockHttpServletRequest request = new MockHttpServletRequest ("GET" , "/services/endpoint" );
268
+ request .setHttpServletMapping (TestMockHttpServletMappings .defaultMapping ());
269
+ assertThat (requestMatcher .matches (request )).isFalse ();
270
+ verify (mvc ).matches (request );
271
+ verifyNoInteractions (ant );
272
+ request .setHttpServletMapping (TestMockHttpServletMappings .path (request , "/services" ));
273
+ assertThat (requestMatcher .matches (request )).isFalse ();
274
+ verify (ant ).matches (request );
275
+ verifyNoMoreInteractions (mvc );
276
+ }
277
+
190
278
private void mockMvcIntrospector (boolean isPresent ) {
191
279
ApplicationContext context = this .matcherRegistry .getApplicationContext ();
192
280
given (context .containsBean ("mvcHandlerMappingIntrospector" )).willReturn (isPresent );
0 commit comments