42
42
import org .springframework .context .ApplicationContext ;
43
43
import org .springframework .core .annotation .MergedAnnotation ;
44
44
import org .springframework .core .annotation .MergedAnnotations ;
45
+ import org .springframework .http .HttpMethod ;
45
46
import org .springframework .security .web .util .matcher .AntPathRequestMatcher ;
46
47
import org .springframework .security .web .util .matcher .OrRequestMatcher ;
47
48
import org .springframework .security .web .util .matcher .RequestMatcher ;
56
57
*
57
58
* @author Madhura Bhave
58
59
* @author Phillip Webb
60
+ * @author Chris Bono
59
61
* @since 2.0.0
60
62
*/
61
63
public final class EndpointRequest {
@@ -212,16 +214,21 @@ protected abstract RequestMatcher createDelegate(WebApplicationContext context,
212
214
213
215
protected final List <RequestMatcher > getDelegateMatchers (RequestMatcherFactory requestMatcherFactory ,
214
216
RequestMatcherProvider matcherProvider , Set <String > paths ) {
217
+ return getDelegateMatchers (requestMatcherFactory , matcherProvider , paths , null );
218
+ }
219
+
220
+ protected final List <RequestMatcher > getDelegateMatchers (RequestMatcherFactory requestMatcherFactory ,
221
+ RequestMatcherProvider matcherProvider , Set <String > paths , HttpMethod httpMethod ) {
215
222
return paths .stream ()
216
- .map ((path ) -> requestMatcherFactory .antPath (matcherProvider , path , "/**" ))
223
+ .map ((path ) -> requestMatcherFactory .antPath (matcherProvider , httpMethod , path , "/**" ))
217
224
.collect (Collectors .toCollection (ArrayList ::new ));
218
225
}
219
226
220
227
protected List <RequestMatcher > getLinksMatchers (RequestMatcherFactory requestMatcherFactory ,
221
228
RequestMatcherProvider matcherProvider , String basePath ) {
222
229
List <RequestMatcher > linksMatchers = new ArrayList <>();
223
- linksMatchers .add (requestMatcherFactory .antPath (matcherProvider , basePath ));
224
- linksMatchers .add (requestMatcherFactory .antPath (matcherProvider , basePath , "/" ));
230
+ linksMatchers .add (requestMatcherFactory .antPath (matcherProvider , null , basePath ));
231
+ linksMatchers .add (requestMatcherFactory .antPath (matcherProvider , null , basePath , "/" ));
225
232
return linksMatchers ;
226
233
}
227
234
@@ -230,7 +237,7 @@ protected RequestMatcherProvider getRequestMatcherProvider(WebApplicationContext
230
237
return context .getBean (RequestMatcherProvider .class );
231
238
}
232
239
catch (NoSuchBeanDefinitionException ex ) {
233
- return AntPathRequestMatcher :: new ;
240
+ return ( pattern , method ) -> new AntPathRequestMatcher ( pattern , ( method != null ) ? method . name () : null ) ;
234
241
}
235
242
}
236
243
@@ -273,38 +280,52 @@ public static final class EndpointRequestMatcher extends AbstractRequestMatcher
273
280
274
281
private final boolean includeLinks ;
275
282
283
+ private final HttpMethod httpMethod ;
284
+
276
285
private EndpointRequestMatcher (boolean includeLinks ) {
277
- this (Collections .emptyList (), Collections .emptyList (), includeLinks );
286
+ this (Collections .emptyList (), Collections .emptyList (), includeLinks , null );
278
287
}
279
288
280
289
private EndpointRequestMatcher (Class <?>[] endpoints , boolean includeLinks ) {
281
- this (Arrays .asList ((Object []) endpoints ), Collections .emptyList (), includeLinks );
290
+ this (Arrays .asList ((Object []) endpoints ), Collections .emptyList (), includeLinks , null );
282
291
}
283
292
284
293
private EndpointRequestMatcher (String [] endpoints , boolean includeLinks ) {
285
- this (Arrays .asList ((Object []) endpoints ), Collections .emptyList (), includeLinks );
294
+ this (Arrays .asList ((Object []) endpoints ), Collections .emptyList (), includeLinks , null );
286
295
}
287
296
288
- private EndpointRequestMatcher (List <Object > includes , List <Object > excludes , boolean includeLinks ) {
297
+ private EndpointRequestMatcher (List <Object > includes , List <Object > excludes , boolean includeLinks ,
298
+ HttpMethod httpMethod ) {
289
299
this .includes = includes ;
290
300
this .excludes = excludes ;
291
301
this .includeLinks = includeLinks ;
302
+ this .httpMethod = httpMethod ;
292
303
}
293
304
294
305
public EndpointRequestMatcher excluding (Class <?>... endpoints ) {
295
306
List <Object > excludes = new ArrayList <>(this .excludes );
296
307
excludes .addAll (Arrays .asList ((Object []) endpoints ));
297
- return new EndpointRequestMatcher (this .includes , excludes , this .includeLinks );
308
+ return new EndpointRequestMatcher (this .includes , excludes , this .includeLinks , null );
298
309
}
299
310
300
311
public EndpointRequestMatcher excluding (String ... endpoints ) {
301
312
List <Object > excludes = new ArrayList <>(this .excludes );
302
313
excludes .addAll (Arrays .asList ((Object []) endpoints ));
303
- return new EndpointRequestMatcher (this .includes , excludes , this .includeLinks );
314
+ return new EndpointRequestMatcher (this .includes , excludes , this .includeLinks , null );
304
315
}
305
316
306
317
public EndpointRequestMatcher excludingLinks () {
307
- return new EndpointRequestMatcher (this .includes , this .excludes , false );
318
+ return new EndpointRequestMatcher (this .includes , this .excludes , false , null );
319
+ }
320
+
321
+ /**
322
+ * Restricts the matcher to only consider requests with a particular http method.
323
+ * @param httpMethod the http method to include
324
+ * @return a copy of the matcher further restricted to only match requests with
325
+ * the specified http method
326
+ */
327
+ public EndpointRequestMatcher withHttpMethod (HttpMethod httpMethod ) {
328
+ return new EndpointRequestMatcher (this .includes , this .excludes , false , httpMethod );
308
329
}
309
330
310
331
@ Override
@@ -318,7 +339,8 @@ protected RequestMatcher createDelegate(WebApplicationContext context,
318
339
}
319
340
streamPaths (this .includes , endpoints ).forEach (paths ::add );
320
341
streamPaths (this .excludes , endpoints ).forEach (paths ::remove );
321
- List <RequestMatcher > delegateMatchers = getDelegateMatchers (requestMatcherFactory , matcherProvider , paths );
342
+ List <RequestMatcher > delegateMatchers = getDelegateMatchers (requestMatcherFactory , matcherProvider , paths ,
343
+ this .httpMethod );
322
344
String basePath = endpoints .getBasePath ();
323
345
if (this .includeLinks && StringUtils .hasText (basePath )) {
324
346
delegateMatchers .addAll (getLinksMatchers (requestMatcherFactory , matcherProvider , basePath ));
@@ -426,12 +448,12 @@ public String toString() {
426
448
*/
427
449
private static final class RequestMatcherFactory {
428
450
429
- RequestMatcher antPath (RequestMatcherProvider matcherProvider , String ... parts ) {
451
+ RequestMatcher antPath (RequestMatcherProvider matcherProvider , HttpMethod httpMethod , String ... parts ) {
430
452
StringBuilder pattern = new StringBuilder ();
431
453
for (String part : parts ) {
432
454
pattern .append (part );
433
455
}
434
- return matcherProvider .getRequestMatcher (pattern .toString ());
456
+ return matcherProvider .getRequestMatcher (pattern .toString (), httpMethod );
435
457
}
436
458
437
459
}
0 commit comments