diff --git a/core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java b/core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java index 3a2576b276..2ea80d31fd 100644 --- a/core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java +++ b/core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java @@ -252,7 +252,7 @@ final class UniqueSecurityAnnotationScanner extends Abstra } for (int i = 0; i < rootParameterTypes.length; i++) { Class resolvedParameterType = ResolvableType.forMethodParameter(candidateMethod, i, sourceDeclaringClass) - .resolve(); + .toClass(); if (rootParameterTypes[i] != resolvedParameterType) { return false; } diff --git a/core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java b/core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java index 757e35a254..88d73ef053 100644 --- a/core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java +++ b/core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.util.ClassUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -275,6 +276,14 @@ public class UniqueSecurityAnnotationScannerTests { assertThat(pre).isNotNull(); } + // gh-17898 + @Test + void scanWhenAnnotationOnParameterizedUndeclaredMethodAndThenLocates() throws Exception { + Method method = ClassUtils.getMethod(GenericInterfaceImpl.class, "processOneAndTwo", Long.class, Object.class); + PreAuthorize pre = this.scanner.scan(method, method.getDeclaringClass()); + assertThat(pre).isNotNull(); + } + @PreAuthorize("one") private interface AnnotationOnInterface { @@ -637,4 +646,27 @@ public class UniqueSecurityAnnotationScannerTests { } + interface GenericInterface { + + @PreAuthorize("hasAuthority('thirtythree')") + void processOneAndTwo(A value1, B value2); + + } + + abstract static class GenericAbstractSuperclass implements GenericInterface { + + @Override + public void processOneAndTwo(Long value1, C value2) { + } + + } + + static class GenericInterfaceImpl extends GenericAbstractSuperclass { + + // The compiler does not require us to declare a concrete + // processOneAndTwo(Long, String) method, and we intentionally + // do not declare one here. + + } + }