11/*
2- * Copyright 2002-2019 the original author or authors.
2+ * Copyright 2002-2022 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2323import org .junit .Test ;
2424
2525import org .springframework .beans .factory .annotation .Autowired ;
26+ import org .springframework .context .annotation .Bean ;
2627import org .springframework .context .annotation .Configuration ;
28+ import org .springframework .core .Ordered ;
29+ import org .springframework .core .annotation .Order ;
2730import org .springframework .mock .web .MockFilterChain ;
2831import org .springframework .mock .web .MockHttpServletRequest ;
2932import org .springframework .mock .web .MockHttpServletResponse ;
3336import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
3437import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
3538import org .springframework .security .web .FilterChainProxy ;
39+ import org .springframework .security .web .SecurityFilterChain ;
3640import org .springframework .web .bind .annotation .RequestMapping ;
3741import org .springframework .web .bind .annotation .RestController ;
3842import org .springframework .web .context .support .AnnotationConfigWebApplicationContext ;
@@ -167,6 +171,38 @@ public void requestMatcherWhensMvcMatcherServletPathInLambdaThenPathIsSecured()
167171 assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_OK );
168172 }
169173
174+ @ Test
175+ public void requestMatcherWhenMultiMvcMatcherInLambdaThenAllPathsAreDenied () throws Exception {
176+ loadConfig (MultiMvcMatcherInLambdaConfig .class );
177+ this .request .setRequestURI ("/test-1" );
178+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
179+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
180+ setup ();
181+ this .request .setRequestURI ("/test-2" );
182+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
183+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
184+ setup ();
185+ this .request .setRequestURI ("/test-3" );
186+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
187+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
188+ }
189+
190+ @ Test
191+ public void requestMatcherWhenMultiMvcMatcherThenAllPathsAreDenied () throws Exception {
192+ loadConfig (MultiMvcMatcherConfig .class );
193+ this .request .setRequestURI ("/test-1" );
194+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
195+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
196+ setup ();
197+ this .request .setRequestURI ("/test-2" );
198+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
199+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
200+ setup ();
201+ this .request .setRequestURI ("/test-3" );
202+ this .springSecurityFilterChain .doFilter (this .request , this .response , this .chain );
203+ assertThat (this .response .getStatus ()).isEqualTo (HttpServletResponse .SC_UNAUTHORIZED );
204+ }
205+
170206 public void loadConfig (Class <?>... configs ) {
171207 this .context = new AnnotationConfigWebApplicationContext ();
172208 this .context .register (configs );
@@ -175,6 +211,101 @@ public void loadConfig(Class<?>... configs) {
175211 this .context .getAutowireCapableBeanFactory ().autowireBean (this );
176212 }
177213
214+ @ EnableWebSecurity
215+ @ Configuration
216+ @ EnableWebMvc
217+ static class MultiMvcMatcherInLambdaConfig {
218+
219+ @ Bean
220+ @ Order (Ordered .HIGHEST_PRECEDENCE )
221+ SecurityFilterChain first (HttpSecurity http ) throws Exception {
222+ // @formatter:off
223+ http
224+ .requestMatchers ((requests ) -> requests
225+ .mvcMatchers ("/test-1" )
226+ .mvcMatchers ("/test-2" )
227+ .mvcMatchers ("/test-3" )
228+ )
229+ .authorizeRequests ((authorize ) -> authorize .anyRequest ().denyAll ())
230+ .httpBasic (withDefaults ());
231+ // @formatter:on
232+ return http .build ();
233+ }
234+
235+ @ Bean
236+ SecurityFilterChain second (HttpSecurity http ) throws Exception {
237+ // @formatter:off
238+ http
239+ .requestMatchers ((requests ) -> requests
240+ .mvcMatchers ("/test-1" )
241+ )
242+ .authorizeRequests ((authorize ) -> authorize
243+ .anyRequest ().permitAll ()
244+ );
245+ // @formatter:on
246+ return http .build ();
247+ }
248+
249+ @ RestController
250+ static class PathController {
251+
252+ @ RequestMapping ({ "/test-1" , "/test-2" , "/test-3" })
253+ String path () {
254+ return "path" ;
255+ }
256+
257+ }
258+
259+ }
260+
261+ @ EnableWebSecurity
262+ @ Configuration
263+ @ EnableWebMvc
264+ static class MultiMvcMatcherConfig {
265+
266+ @ Bean
267+ @ Order (Ordered .HIGHEST_PRECEDENCE )
268+ SecurityFilterChain first (HttpSecurity http ) throws Exception {
269+ // @formatter:off
270+ http
271+ .requestMatchers ()
272+ .mvcMatchers ("/test-1" )
273+ .mvcMatchers ("/test-2" )
274+ .mvcMatchers ("/test-3" )
275+ .and ()
276+ .authorizeRequests ()
277+ .anyRequest ().denyAll ()
278+ .and ()
279+ .httpBasic (withDefaults ());
280+ // @formatter:on
281+ return http .build ();
282+ }
283+
284+ @ Bean
285+ SecurityFilterChain second (HttpSecurity http ) throws Exception {
286+ // @formatter:off
287+ http
288+ .requestMatchers ()
289+ .mvcMatchers ("/test-1" )
290+ .and ()
291+ .authorizeRequests ()
292+ .anyRequest ().permitAll ();
293+ // @formatter:on
294+ return http .build ();
295+ }
296+
297+ @ RestController
298+ static class PathController {
299+
300+ @ RequestMapping ({ "/test-1" , "/test-2" , "/test-3" })
301+ String path () {
302+ return "path" ;
303+ }
304+
305+ }
306+
307+ }
308+
178309 @ EnableWebSecurity
179310 @ Configuration
180311 @ EnableWebMvc
0 commit comments