1616
1717package org .springframework .security .core .annotation ;
1818
19+ import java .lang .annotation .ElementType ;
20+ import java .lang .annotation .Retention ;
21+ import java .lang .annotation .RetentionPolicy ;
22+ import java .lang .annotation .Target ;
1923import java .lang .reflect .Method ;
24+ import java .lang .reflect .Parameter ;
25+ import java .util .List ;
2026
2127import org .junit .jupiter .api .Test ;
2228
@@ -34,6 +40,9 @@ public class UniqueSecurityAnnotationScannerTests {
3440 private UniqueSecurityAnnotationScanner <PreAuthorize > scanner = new UniqueSecurityAnnotationScanner <>(
3541 PreAuthorize .class );
3642
43+ private UniqueSecurityAnnotationScanner <CustomParameterAnnotation > parameterScanner = new UniqueSecurityAnnotationScanner <>(
44+ CustomParameterAnnotation .class );
45+
3746 @ Test
3847 void scanWhenAnnotationOnInterfaceThenResolves () throws Exception {
3948 Method method = AnnotationOnInterface .class .getDeclaredMethod ("method" );
@@ -251,6 +260,101 @@ void scanWhenClassInheritingAbstractClassNoAnnotationsThenNoAnnotation() throws
251260 assertThat (preAuthorize ).isNull ();
252261 }
253262
263+ @ Test
264+ void scanParameterAnnotationWhenAnnotationOnInterface () throws Exception {
265+ Parameter parameter = UserService .class .getDeclaredMethod ("add" , String .class ).getParameters ()[0 ];
266+ CustomParameterAnnotation customParameterAnnotation = this .parameterScanner .scan (parameter );
267+ assertThat (customParameterAnnotation .value ()).isEqualTo ("one" );
268+ }
269+
270+ @ Test
271+ void scanParameterAnnotationWhenClassInheritingInterfaceAnnotation () throws Exception {
272+ Parameter parameter = UserServiceImpl .class .getDeclaredMethod ("add" , String .class ).getParameters ()[0 ];
273+ CustomParameterAnnotation customParameterAnnotation = this .parameterScanner .scan (parameter );
274+ assertThat (customParameterAnnotation .value ()).isEqualTo ("one" );
275+ }
276+
277+ @ Test
278+ void scanParameterAnnotationWhenClassOverridingMethodOverridingInterface () throws Exception {
279+ Parameter parameter = UserServiceImpl .class .getDeclaredMethod ("get" , String .class ).getParameters ()[0 ];
280+ CustomParameterAnnotation customParameterAnnotation = this .parameterScanner .scan (parameter );
281+ assertThat (customParameterAnnotation .value ()).isEqualTo ("five" );
282+ }
283+
284+ @ Test
285+ void scanParameterAnnotationWhenMultipleMethodInheritanceThenException () throws Exception {
286+ Parameter parameter = UserServiceImpl .class .getDeclaredMethod ("list" , String .class ).getParameters ()[0 ];
287+ assertThatExceptionOfType (AnnotationConfigurationException .class )
288+ .isThrownBy (() -> this .parameterScanner .scan (parameter ));
289+ }
290+
291+ @ Test
292+ void scanParameterAnnotationWhenInterfaceNoAnnotationsThenException () throws Exception {
293+ Parameter parameter = UserServiceImpl .class .getDeclaredMethod ("delete" , String .class ).getParameters ()[0 ];
294+ assertThatExceptionOfType (AnnotationConfigurationException .class )
295+ .isThrownBy (() -> this .parameterScanner .scan (parameter ));
296+ }
297+
298+ interface UserService {
299+
300+ void add (@ CustomParameterAnnotation ("one" ) String user );
301+
302+ List <String > list (@ CustomParameterAnnotation ("two" ) String user );
303+
304+ String get (@ CustomParameterAnnotation ("three" ) String user );
305+
306+ void delete (@ CustomParameterAnnotation ("five" ) String user );
307+
308+ }
309+
310+ interface OtherUserService {
311+
312+ List <String > list (@ CustomParameterAnnotation ("four" ) String user );
313+
314+ }
315+
316+ interface ThirdPartyUserService {
317+
318+ void delete (@ CustomParameterAnnotation ("five" ) String user );
319+
320+ }
321+
322+ interface RemoteUserService extends ThirdPartyUserService {
323+
324+ }
325+
326+ static class UserServiceImpl implements UserService , OtherUserService , RemoteUserService {
327+
328+ @ Override
329+ public void add (String user ) {
330+
331+ }
332+
333+ @ Override
334+ public List <String > list (String user ) {
335+ return List .of (user );
336+ }
337+
338+ @ Override
339+ public String get (@ CustomParameterAnnotation ("five" ) String user ) {
340+ return user ;
341+ }
342+
343+ @ Override
344+ public void delete (String user ) {
345+
346+ }
347+
348+ }
349+
350+ @ Target ({ ElementType .PARAMETER })
351+ @ Retention (RetentionPolicy .RUNTIME )
352+ @interface CustomParameterAnnotation {
353+
354+ String value ();
355+
356+ }
357+
254358 @ PreAuthorize ("one" )
255359 private interface AnnotationOnInterface {
256360
0 commit comments